All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Lezcano <daniel.lezcano@linaro.org>
To: Ulf Hansson <ulf.hansson@linaro.org>
Cc: linux-arm-kernel@lists.infradead.org,
	Russell King <linux@arm.linux.org.uk>,
	linux-mmc@vger.kernel.org, Chris Ball <cjb@laptop.org>,
	Linus Walleij <linus.walleij@linaro.org>
Subject: Re: [PATCH V3 4/4] mmc: mmci: Save and restore register context
Date: Tue, 03 Sep 2013 11:53:02 +0200	[thread overview]
Message-ID: <5225B17E.8090908@linaro.org> (raw)
In-Reply-To: <1378200576-13413-5-git-send-email-ulf.hansson@linaro.org>

On 09/03/2013 11:29 AM, Ulf Hansson wrote:
> If a corresponding power domain exists for the device and it manages
> to cut the domain regulator while the device is runtime suspended,
> the IP loses it's registers context. We restore the context in the
> .runtime_resume callback from the existing register caches to adapt
> to this siutuation.
> 
> We also want to make sure the registers are in a known state while
> restoring context in the case when the power domain did not drop the
> power, since there are restrictions for the order of writing to these
> registers. To handle this, we clear the registers in the
> .runtime_suspend callback.
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> Acked-by: Rickard Andersson <rickard.andersson@stericsson.com>
> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---

Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>



>  drivers/mmc/host/mmci.c |   43 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
> 
> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
> index 82afcd3..97e541b 100644
> --- a/drivers/mmc/host/mmci.c
> +++ b/drivers/mmc/host/mmci.c
> @@ -62,6 +62,7 @@ static unsigned int fmax = 515633;
>   * @signal_direction: input/out direction of bus signals can be indicated
>   * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
>   * @busy_detect: true if busy detection on dat0 is supported
> + * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
>   */
>  struct variant_data {
>  	unsigned int		clkreg;
> @@ -76,6 +77,7 @@ struct variant_data {
>  	bool			signal_direction;
>  	bool			pwrreg_clkgate;
>  	bool			busy_detect;
> +	bool			pwrreg_nopower;
>  };
>  
>  static struct variant_data variant_arm = {
> @@ -109,6 +111,7 @@ static struct variant_data variant_u300 = {
>  	.pwrreg_powerup		= MCI_PWR_ON,
>  	.signal_direction	= true,
>  	.pwrreg_clkgate		= true,
> +	.pwrreg_nopower		= true,
>  };
>  
>  static struct variant_data variant_nomadik = {
> @@ -121,6 +124,7 @@ static struct variant_data variant_nomadik = {
>  	.pwrreg_powerup		= MCI_PWR_ON,
>  	.signal_direction	= true,
>  	.pwrreg_clkgate		= true,
> +	.pwrreg_nopower		= true,
>  };
>  
>  static struct variant_data variant_ux500 = {
> @@ -135,6 +139,7 @@ static struct variant_data variant_ux500 = {
>  	.signal_direction	= true,
>  	.pwrreg_clkgate		= true,
>  	.busy_detect		= true,
> +	.pwrreg_nopower		= true,
>  };
>  
>  static struct variant_data variant_ux500v2 = {
> @@ -150,6 +155,7 @@ static struct variant_data variant_ux500v2 = {
>  	.signal_direction	= true,
>  	.pwrreg_clkgate		= true,
>  	.busy_detect		= true,
> +	.pwrreg_nopower		= true,
>  };
>  
>  static int mmci_card_busy(struct mmc_host *mmc)
> @@ -1759,6 +1765,41 @@ static int mmci_resume(struct device *dev)
>  #endif
>  
>  #ifdef CONFIG_PM_RUNTIME
> +static void mmci_save(struct mmci_host *host)
> +{
> +	unsigned long flags;
> +
> +	if (host->variant->pwrreg_nopower) {
> +		spin_lock_irqsave(&host->lock, flags);
> +
> +		writel(0, host->base + MMCIMASK0);
> +		writel(0, host->base + MMCIDATACTRL);
> +		writel(0, host->base + MMCIPOWER);
> +		writel(0, host->base + MMCICLOCK);
> +		mmci_reg_delay(host);
> +
> +		spin_unlock_irqrestore(&host->lock, flags);
> +	}
> +
> +}
> +
> +static void mmci_restore(struct mmci_host *host)
> +{
> +	unsigned long flags;
> +
> +	if (host->variant->pwrreg_nopower) {
> +		spin_lock_irqsave(&host->lock, flags);
> +
> +		writel(host->clk_reg, host->base + MMCICLOCK);
> +		writel(host->datactrl_reg, host->base + MMCIDATACTRL);
> +		writel(host->pwr_reg, host->base + MMCIPOWER);
> +		writel(MCI_IRQENABLE, host->base + MMCIMASK0);
> +		mmci_reg_delay(host);
> +
> +		spin_unlock_irqrestore(&host->lock, flags);
> +	}
> +}
> +
>  static int mmci_runtime_suspend(struct device *dev)
>  {
>  	struct amba_device *adev = to_amba_device(dev);
> @@ -1767,6 +1808,7 @@ static int mmci_runtime_suspend(struct device *dev)
>  	if (mmc) {
>  		struct mmci_host *host = mmc_priv(mmc);
>  		pinctrl_pm_select_sleep_state(dev);
> +		mmci_save(host);
>  		clk_disable_unprepare(host->clk);
>  	}
>  
> @@ -1781,6 +1823,7 @@ static int mmci_runtime_resume(struct device *dev)
>  	if (mmc) {
>  		struct mmci_host *host = mmc_priv(mmc);
>  		clk_prepare_enable(host->clk);
> +		mmci_restore(host);
>  		pinctrl_pm_select_default_state(dev);
>  	}
>  
> 


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


WARNING: multiple messages have this Message-ID (diff)
From: daniel.lezcano@linaro.org (Daniel Lezcano)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH V3 4/4] mmc: mmci: Save and restore register context
Date: Tue, 03 Sep 2013 11:53:02 +0200	[thread overview]
Message-ID: <5225B17E.8090908@linaro.org> (raw)
In-Reply-To: <1378200576-13413-5-git-send-email-ulf.hansson@linaro.org>

On 09/03/2013 11:29 AM, Ulf Hansson wrote:
> If a corresponding power domain exists for the device and it manages
> to cut the domain regulator while the device is runtime suspended,
> the IP loses it's registers context. We restore the context in the
> .runtime_resume callback from the existing register caches to adapt
> to this siutuation.
> 
> We also want to make sure the registers are in a known state while
> restoring context in the case when the power domain did not drop the
> power, since there are restrictions for the order of writing to these
> registers. To handle this, we clear the registers in the
> .runtime_suspend callback.
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> Acked-by: Rickard Andersson <rickard.andersson@stericsson.com>
> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> ---

Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>



>  drivers/mmc/host/mmci.c |   43 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
> 
> diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
> index 82afcd3..97e541b 100644
> --- a/drivers/mmc/host/mmci.c
> +++ b/drivers/mmc/host/mmci.c
> @@ -62,6 +62,7 @@ static unsigned int fmax = 515633;
>   * @signal_direction: input/out direction of bus signals can be indicated
>   * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
>   * @busy_detect: true if busy detection on dat0 is supported
> + * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
>   */
>  struct variant_data {
>  	unsigned int		clkreg;
> @@ -76,6 +77,7 @@ struct variant_data {
>  	bool			signal_direction;
>  	bool			pwrreg_clkgate;
>  	bool			busy_detect;
> +	bool			pwrreg_nopower;
>  };
>  
>  static struct variant_data variant_arm = {
> @@ -109,6 +111,7 @@ static struct variant_data variant_u300 = {
>  	.pwrreg_powerup		= MCI_PWR_ON,
>  	.signal_direction	= true,
>  	.pwrreg_clkgate		= true,
> +	.pwrreg_nopower		= true,
>  };
>  
>  static struct variant_data variant_nomadik = {
> @@ -121,6 +124,7 @@ static struct variant_data variant_nomadik = {
>  	.pwrreg_powerup		= MCI_PWR_ON,
>  	.signal_direction	= true,
>  	.pwrreg_clkgate		= true,
> +	.pwrreg_nopower		= true,
>  };
>  
>  static struct variant_data variant_ux500 = {
> @@ -135,6 +139,7 @@ static struct variant_data variant_ux500 = {
>  	.signal_direction	= true,
>  	.pwrreg_clkgate		= true,
>  	.busy_detect		= true,
> +	.pwrreg_nopower		= true,
>  };
>  
>  static struct variant_data variant_ux500v2 = {
> @@ -150,6 +155,7 @@ static struct variant_data variant_ux500v2 = {
>  	.signal_direction	= true,
>  	.pwrreg_clkgate		= true,
>  	.busy_detect		= true,
> +	.pwrreg_nopower		= true,
>  };
>  
>  static int mmci_card_busy(struct mmc_host *mmc)
> @@ -1759,6 +1765,41 @@ static int mmci_resume(struct device *dev)
>  #endif
>  
>  #ifdef CONFIG_PM_RUNTIME
> +static void mmci_save(struct mmci_host *host)
> +{
> +	unsigned long flags;
> +
> +	if (host->variant->pwrreg_nopower) {
> +		spin_lock_irqsave(&host->lock, flags);
> +
> +		writel(0, host->base + MMCIMASK0);
> +		writel(0, host->base + MMCIDATACTRL);
> +		writel(0, host->base + MMCIPOWER);
> +		writel(0, host->base + MMCICLOCK);
> +		mmci_reg_delay(host);
> +
> +		spin_unlock_irqrestore(&host->lock, flags);
> +	}
> +
> +}
> +
> +static void mmci_restore(struct mmci_host *host)
> +{
> +	unsigned long flags;
> +
> +	if (host->variant->pwrreg_nopower) {
> +		spin_lock_irqsave(&host->lock, flags);
> +
> +		writel(host->clk_reg, host->base + MMCICLOCK);
> +		writel(host->datactrl_reg, host->base + MMCIDATACTRL);
> +		writel(host->pwr_reg, host->base + MMCIPOWER);
> +		writel(MCI_IRQENABLE, host->base + MMCIMASK0);
> +		mmci_reg_delay(host);
> +
> +		spin_unlock_irqrestore(&host->lock, flags);
> +	}
> +}
> +
>  static int mmci_runtime_suspend(struct device *dev)
>  {
>  	struct amba_device *adev = to_amba_device(dev);
> @@ -1767,6 +1808,7 @@ static int mmci_runtime_suspend(struct device *dev)
>  	if (mmc) {
>  		struct mmci_host *host = mmc_priv(mmc);
>  		pinctrl_pm_select_sleep_state(dev);
> +		mmci_save(host);
>  		clk_disable_unprepare(host->clk);
>  	}
>  
> @@ -1781,6 +1823,7 @@ static int mmci_runtime_resume(struct device *dev)
>  	if (mmc) {
>  		struct mmci_host *host = mmc_priv(mmc);
>  		clk_prepare_enable(host->clk);
> +		mmci_restore(host);
>  		pinctrl_pm_select_default_state(dev);
>  	}
>  
> 


-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

  reply	other threads:[~2013-09-03  9:53 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-03  9:29 [PATCH V3 0/4] mmc: mmci: Support ap_sleep in cpuidle for ux500 Ulf Hansson
2013-09-03  9:29 ` Ulf Hansson
2013-09-03  9:29 ` [PATCH V3 1/4] mmc: mmci: Adapt to new pinctrl handling Ulf Hansson
2013-09-03  9:29   ` Ulf Hansson
2013-09-04  5:42   ` Linus Walleij
2013-09-04  5:42     ` Linus Walleij
2013-09-03  9:29 ` [PATCH V3 2/4] mmc: mmci: Use optional sleep pinctrl state Ulf Hansson
2013-09-03  9:29   ` Ulf Hansson
2013-09-04  5:43   ` Linus Walleij
2013-09-04  5:43     ` Linus Walleij
2013-09-03  9:29 ` [PATCH V3 3/4] mmc: mmci: Adapt to register write restrictions Ulf Hansson
2013-09-03  9:29   ` Ulf Hansson
2013-09-03  9:50   ` Daniel Lezcano
2013-09-03  9:50     ` Daniel Lezcano
2013-09-03 11:56     ` Ulf Hansson
2013-09-03 11:56       ` Ulf Hansson
2013-09-03  9:29 ` [PATCH V3 4/4] mmc: mmci: Save and restore register context Ulf Hansson
2013-09-03  9:29   ` Ulf Hansson
2013-09-03  9:53   ` Daniel Lezcano [this message]
2013-09-03  9:53     ` Daniel Lezcano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5225B17E.8090908@linaro.org \
    --to=daniel.lezcano@linaro.org \
    --cc=cjb@laptop.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=ulf.hansson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.