All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] mmc: sdhci-esdhc-imx: fix abort due to missing runtime PM
@ 2015-03-30 11:37 ` Stefan Agner
  0 siblings, 0 replies; 10+ messages in thread
From: Stefan Agner @ 2015-03-30 11:37 UTC (permalink / raw)
  To: chris, ulf.hansson, anton
  Cc: rmk+kernel, b29396, shawn.guo, linux-mmc, linux-arm-kernel,
	linux-kernel, stefan

When entering suspend while the device is in runtime PM, the
sdhci_(suspend|resume)_host function are called with disabled clocks.
Since this functions access the SDHC host registers, this leads to an
external abort on Vybrid SoC:

[   37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000
[   37.780304] Internal error: : 1c06 [#1] ARM
[   37.784670] Modules linked in:
[   37.787908] CPU: 0 PID: 428 Comm: sh Not tainted 3.18.0-rc5-00119-geefd097-dirty #1540
[   37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000
[   37.801785] PC is at esdhc_writel_le+0x40/0xec
[   37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4
[   37.811877] pc : [<803f0584>]    lr : [<803eaaa0>]    psr: 400f0013
[   37.811877] sp : 8ca6dd28  ip : 00000001  fp : 8ca6dd3c
[   37.823766] r10: 807a233c  r9 : 00000000  r8 : 8e8b7210
[   37.829194] r7 : 802d8a08  r6 : 8082e928  r5 : 00000000  r4 : 00000002
[   37.835974] r3 : 8ea34e90  r2 : 00000038  r1 : 00000000  r0 : 8ea32ac0
...

Clocks need to be enabled to access the registers. Fix the issue by
add driver specific implementation of suspend/resume functions which
take care of clocks using runtime PM API.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
The first version of this patch was part of a patchset sent back in
december. While the second patch of the patchset back then is invalid,
this fix is required to avoid the abort when switching into suspend
mode on Vybrid SoC.

During review of this patch I realized that my proposed solution to
fix this in the suspend/resume functions in sdhci-pltfm.c is not a
good idea since a lot of drivers use this functions without using the
runtime PM APIs.

Changes since v1:
- Create new sdhci_esdhc_(suspend|resume) functions in favor of adding a
  hard requirement for runtime PM on SDHC platform implementations

 drivers/mmc/host/sdhci-esdhc-imx.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 10ef824..84b3365 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1119,6 +1119,32 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
+static int sdhci_esdhc_suspend(struct device *dev)
+{
+	int ret;
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+	ret = sdhci_suspend_host(host);
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+
+static int sdhci_esdhc_resume(struct device *dev)
+{
+	int ret;
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+	ret = sdhci_resume_host(host);
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+
 static int sdhci_esdhc_runtime_suspend(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
@@ -1154,7 +1180,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
 #endif
 
 static const struct dev_pm_ops sdhci_esdhc_pmops = {
-	SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, sdhci_pltfm_resume)
+	SET_SYSTEM_SLEEP_PM_OPS(sdhci_esdhc_suspend, sdhci_esdhc_resume)
 	SET_RUNTIME_PM_OPS(sdhci_esdhc_runtime_suspend,
 				sdhci_esdhc_runtime_resume, NULL)
 };
-- 
2.3.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2] mmc: sdhci-esdhc-imx: fix abort due to missing runtime PM
@ 2015-03-30 11:37 ` Stefan Agner
  0 siblings, 0 replies; 10+ messages in thread
From: Stefan Agner @ 2015-03-30 11:37 UTC (permalink / raw)
  To: linux-arm-kernel

When entering suspend while the device is in runtime PM, the
sdhci_(suspend|resume)_host function are called with disabled clocks.
Since this functions access the SDHC host registers, this leads to an
external abort on Vybrid SoC:

[   37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000
[   37.780304] Internal error: : 1c06 [#1] ARM
[   37.784670] Modules linked in:
[   37.787908] CPU: 0 PID: 428 Comm: sh Not tainted 3.18.0-rc5-00119-geefd097-dirty #1540
[   37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000
[   37.801785] PC is at esdhc_writel_le+0x40/0xec
[   37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4
[   37.811877] pc : [<803f0584>]    lr : [<803eaaa0>]    psr: 400f0013
[   37.811877] sp : 8ca6dd28  ip : 00000001  fp : 8ca6dd3c
[   37.823766] r10: 807a233c  r9 : 00000000  r8 : 8e8b7210
[   37.829194] r7 : 802d8a08  r6 : 8082e928  r5 : 00000000  r4 : 00000002
[   37.835974] r3 : 8ea34e90  r2 : 00000038  r1 : 00000000  r0 : 8ea32ac0
...

Clocks need to be enabled to access the registers. Fix the issue by
add driver specific implementation of suspend/resume functions which
take care of clocks using runtime PM API.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
The first version of this patch was part of a patchset sent back in
december. While the second patch of the patchset back then is invalid,
this fix is required to avoid the abort when switching into suspend
mode on Vybrid SoC.

During review of this patch I realized that my proposed solution to
fix this in the suspend/resume functions in sdhci-pltfm.c is not a
good idea since a lot of drivers use this functions without using the
runtime PM APIs.

Changes since v1:
- Create new sdhci_esdhc_(suspend|resume) functions in favor of adding a
  hard requirement for runtime PM on SDHC platform implementations

 drivers/mmc/host/sdhci-esdhc-imx.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 10ef824..84b3365 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1119,6 +1119,32 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
+static int sdhci_esdhc_suspend(struct device *dev)
+{
+	int ret;
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+	ret = sdhci_suspend_host(host);
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+
+static int sdhci_esdhc_resume(struct device *dev)
+{
+	int ret;
+	struct sdhci_host *host = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+	ret = sdhci_resume_host(host);
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+
 static int sdhci_esdhc_runtime_suspend(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
@@ -1154,7 +1180,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
 #endif
 
 static const struct dev_pm_ops sdhci_esdhc_pmops = {
-	SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, sdhci_pltfm_resume)
+	SET_SYSTEM_SLEEP_PM_OPS(sdhci_esdhc_suspend, sdhci_esdhc_resume)
 	SET_RUNTIME_PM_OPS(sdhci_esdhc_runtime_suspend,
 				sdhci_esdhc_runtime_resume, NULL)
 };
-- 
2.3.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] mmc: sdhci-esdhc-imx: fix abort due to missing runtime PM
  2015-03-30 11:37 ` Stefan Agner
  (?)
@ 2015-05-06 12:07   ` Ulf Hansson
  -1 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2015-05-06 12:07 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Chris Ball, Anton Vorontsov, Russell King, Dong Aisheng,
	Shawn Guo, linux-mmc, linux-arm-kernel, linux-kernel

On 30 March 2015 at 13:37, Stefan Agner <stefan@agner.ch> wrote:
> When entering suspend while the device is in runtime PM, the
> sdhci_(suspend|resume)_host function are called with disabled clocks.
> Since this functions access the SDHC host registers, this leads to an
> external abort on Vybrid SoC:
>
> [   37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000
> [   37.780304] Internal error: : 1c06 [#1] ARM
> [   37.784670] Modules linked in:
> [   37.787908] CPU: 0 PID: 428 Comm: sh Not tainted 3.18.0-rc5-00119-geefd097-dirty #1540
> [   37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000
> [   37.801785] PC is at esdhc_writel_le+0x40/0xec
> [   37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4
> [   37.811877] pc : [<803f0584>]    lr : [<803eaaa0>]    psr: 400f0013
> [   37.811877] sp : 8ca6dd28  ip : 00000001  fp : 8ca6dd3c
> [   37.823766] r10: 807a233c  r9 : 00000000  r8 : 8e8b7210
> [   37.829194] r7 : 802d8a08  r6 : 8082e928  r5 : 00000000  r4 : 00000002
> [   37.835974] r3 : 8ea34e90  r2 : 00000038  r1 : 00000000  r0 : 8ea32ac0
> ...
>
> Clocks need to be enabled to access the registers. Fix the issue by
> add driver specific implementation of suspend/resume functions which
> take care of clocks using runtime PM API.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>

Hi Stefan,

Sorry for the delay.

Indeed sdhci seems to have some issues when combining runtime PM and system PM.

> ---
> The first version of this patch was part of a patchset sent back in
> december. While the second patch of the patchset back then is invalid,
> this fix is required to avoid the abort when switching into suspend
> mode on Vybrid SoC.
>
> During review of this patch I realized that my proposed solution to
> fix this in the suspend/resume functions in sdhci-pltfm.c is not a
> good idea since a lot of drivers use this functions without using the
> runtime PM APIs.
>
> Changes since v1:
> - Create new sdhci_esdhc_(suspend|resume) functions in favor of adding a
>   hard requirement for runtime PM on SDHC platform implementations
>
>  drivers/mmc/host/sdhci-esdhc-imx.c | 28 +++++++++++++++++++++++++++-
>  1 file changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 10ef824..84b3365 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -1119,6 +1119,32 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
>  }
>
>  #ifdef CONFIG_PM
> +static int sdhci_esdhc_suspend(struct device *dev)
> +{
> +       int ret;
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       pm_runtime_get_sync(dev);

This is indeed needed, since else it isn't safe to invoke sdhci_suspend_host().

> +       ret = sdhci_suspend_host(host);
> +       pm_runtime_mark_last_busy(dev);
> +       pm_runtime_put_autosuspend(dev);

The problem is, that this wont do what you think I believe.

The device will be kept runtime PM resumed, since the PM core has
increased a runtime PM reference count for your device, in the
->prepare() phase (pm_runtime_get_noresume()).

Potentially pm_runtime_force_suspend() could help you accomplish what you want.

> +
> +       return ret;
> +}
> +
> +static int sdhci_esdhc_resume(struct device *dev)
> +{
> +       int ret;
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       pm_runtime_get_sync(dev);
> +       ret = sdhci_resume_host(host);
> +       pm_runtime_mark_last_busy(dev);
> +       pm_runtime_put_autosuspend(dev);
> +

Similar comments as above.

> +       return ret;
> +}
> +
>  static int sdhci_esdhc_runtime_suspend(struct device *dev)
>  {
>         struct sdhci_host *host = dev_get_drvdata(dev);
> @@ -1154,7 +1180,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
>  #endif
>
>  static const struct dev_pm_ops sdhci_esdhc_pmops = {
> -       SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, sdhci_pltfm_resume)
> +       SET_SYSTEM_SLEEP_PM_OPS(sdhci_esdhc_suspend, sdhci_esdhc_resume)
>         SET_RUNTIME_PM_OPS(sdhci_esdhc_runtime_suspend,
>                                 sdhci_esdhc_runtime_resume, NULL)
>  };
> --
> 2.3.3
>

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] mmc: sdhci-esdhc-imx: fix abort due to missing runtime PM
@ 2015-05-06 12:07   ` Ulf Hansson
  0 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2015-05-06 12:07 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Chris Ball, Anton Vorontsov, Russell King, Dong Aisheng,
	Shawn Guo, linux-mmc, linux-arm-kernel, linux-kernel

On 30 March 2015 at 13:37, Stefan Agner <stefan@agner.ch> wrote:
> When entering suspend while the device is in runtime PM, the
> sdhci_(suspend|resume)_host function are called with disabled clocks.
> Since this functions access the SDHC host registers, this leads to an
> external abort on Vybrid SoC:
>
> [   37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000
> [   37.780304] Internal error: : 1c06 [#1] ARM
> [   37.784670] Modules linked in:
> [   37.787908] CPU: 0 PID: 428 Comm: sh Not tainted 3.18.0-rc5-00119-geefd097-dirty #1540
> [   37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000
> [   37.801785] PC is at esdhc_writel_le+0x40/0xec
> [   37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4
> [   37.811877] pc : [<803f0584>]    lr : [<803eaaa0>]    psr: 400f0013
> [   37.811877] sp : 8ca6dd28  ip : 00000001  fp : 8ca6dd3c
> [   37.823766] r10: 807a233c  r9 : 00000000  r8 : 8e8b7210
> [   37.829194] r7 : 802d8a08  r6 : 8082e928  r5 : 00000000  r4 : 00000002
> [   37.835974] r3 : 8ea34e90  r2 : 00000038  r1 : 00000000  r0 : 8ea32ac0
> ...
>
> Clocks need to be enabled to access the registers. Fix the issue by
> add driver specific implementation of suspend/resume functions which
> take care of clocks using runtime PM API.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>

Hi Stefan,

Sorry for the delay.

Indeed sdhci seems to have some issues when combining runtime PM and system PM.

> ---
> The first version of this patch was part of a patchset sent back in
> december. While the second patch of the patchset back then is invalid,
> this fix is required to avoid the abort when switching into suspend
> mode on Vybrid SoC.
>
> During review of this patch I realized that my proposed solution to
> fix this in the suspend/resume functions in sdhci-pltfm.c is not a
> good idea since a lot of drivers use this functions without using the
> runtime PM APIs.
>
> Changes since v1:
> - Create new sdhci_esdhc_(suspend|resume) functions in favor of adding a
>   hard requirement for runtime PM on SDHC platform implementations
>
>  drivers/mmc/host/sdhci-esdhc-imx.c | 28 +++++++++++++++++++++++++++-
>  1 file changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 10ef824..84b3365 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -1119,6 +1119,32 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
>  }
>
>  #ifdef CONFIG_PM
> +static int sdhci_esdhc_suspend(struct device *dev)
> +{
> +       int ret;
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       pm_runtime_get_sync(dev);

This is indeed needed, since else it isn't safe to invoke sdhci_suspend_host().

> +       ret = sdhci_suspend_host(host);
> +       pm_runtime_mark_last_busy(dev);
> +       pm_runtime_put_autosuspend(dev);

The problem is, that this wont do what you think I believe.

The device will be kept runtime PM resumed, since the PM core has
increased a runtime PM reference count for your device, in the
->prepare() phase (pm_runtime_get_noresume()).

Potentially pm_runtime_force_suspend() could help you accomplish what you want.

> +
> +       return ret;
> +}
> +
> +static int sdhci_esdhc_resume(struct device *dev)
> +{
> +       int ret;
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       pm_runtime_get_sync(dev);
> +       ret = sdhci_resume_host(host);
> +       pm_runtime_mark_last_busy(dev);
> +       pm_runtime_put_autosuspend(dev);
> +

Similar comments as above.

> +       return ret;
> +}
> +
>  static int sdhci_esdhc_runtime_suspend(struct device *dev)
>  {
>         struct sdhci_host *host = dev_get_drvdata(dev);
> @@ -1154,7 +1180,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
>  #endif
>
>  static const struct dev_pm_ops sdhci_esdhc_pmops = {
> -       SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, sdhci_pltfm_resume)
> +       SET_SYSTEM_SLEEP_PM_OPS(sdhci_esdhc_suspend, sdhci_esdhc_resume)
>         SET_RUNTIME_PM_OPS(sdhci_esdhc_runtime_suspend,
>                                 sdhci_esdhc_runtime_resume, NULL)
>  };
> --
> 2.3.3
>

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2] mmc: sdhci-esdhc-imx: fix abort due to missing runtime PM
@ 2015-05-06 12:07   ` Ulf Hansson
  0 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2015-05-06 12:07 UTC (permalink / raw)
  To: linux-arm-kernel

On 30 March 2015 at 13:37, Stefan Agner <stefan@agner.ch> wrote:
> When entering suspend while the device is in runtime PM, the
> sdhci_(suspend|resume)_host function are called with disabled clocks.
> Since this functions access the SDHC host registers, this leads to an
> external abort on Vybrid SoC:
>
> [   37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000
> [   37.780304] Internal error: : 1c06 [#1] ARM
> [   37.784670] Modules linked in:
> [   37.787908] CPU: 0 PID: 428 Comm: sh Not tainted 3.18.0-rc5-00119-geefd097-dirty #1540
> [   37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000
> [   37.801785] PC is at esdhc_writel_le+0x40/0xec
> [   37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4
> [   37.811877] pc : [<803f0584>]    lr : [<803eaaa0>]    psr: 400f0013
> [   37.811877] sp : 8ca6dd28  ip : 00000001  fp : 8ca6dd3c
> [   37.823766] r10: 807a233c  r9 : 00000000  r8 : 8e8b7210
> [   37.829194] r7 : 802d8a08  r6 : 8082e928  r5 : 00000000  r4 : 00000002
> [   37.835974] r3 : 8ea34e90  r2 : 00000038  r1 : 00000000  r0 : 8ea32ac0
> ...
>
> Clocks need to be enabled to access the registers. Fix the issue by
> add driver specific implementation of suspend/resume functions which
> take care of clocks using runtime PM API.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>

Hi Stefan,

Sorry for the delay.

Indeed sdhci seems to have some issues when combining runtime PM and system PM.

> ---
> The first version of this patch was part of a patchset sent back in
> december. While the second patch of the patchset back then is invalid,
> this fix is required to avoid the abort when switching into suspend
> mode on Vybrid SoC.
>
> During review of this patch I realized that my proposed solution to
> fix this in the suspend/resume functions in sdhci-pltfm.c is not a
> good idea since a lot of drivers use this functions without using the
> runtime PM APIs.
>
> Changes since v1:
> - Create new sdhci_esdhc_(suspend|resume) functions in favor of adding a
>   hard requirement for runtime PM on SDHC platform implementations
>
>  drivers/mmc/host/sdhci-esdhc-imx.c | 28 +++++++++++++++++++++++++++-
>  1 file changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 10ef824..84b3365 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -1119,6 +1119,32 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
>  }
>
>  #ifdef CONFIG_PM
> +static int sdhci_esdhc_suspend(struct device *dev)
> +{
> +       int ret;
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       pm_runtime_get_sync(dev);

This is indeed needed, since else it isn't safe to invoke sdhci_suspend_host().

> +       ret = sdhci_suspend_host(host);
> +       pm_runtime_mark_last_busy(dev);
> +       pm_runtime_put_autosuspend(dev);

The problem is, that this wont do what you think I believe.

The device will be kept runtime PM resumed, since the PM core has
increased a runtime PM reference count for your device, in the
->prepare() phase (pm_runtime_get_noresume()).

Potentially pm_runtime_force_suspend() could help you accomplish what you want.

> +
> +       return ret;
> +}
> +
> +static int sdhci_esdhc_resume(struct device *dev)
> +{
> +       int ret;
> +       struct sdhci_host *host = dev_get_drvdata(dev);
> +
> +       pm_runtime_get_sync(dev);
> +       ret = sdhci_resume_host(host);
> +       pm_runtime_mark_last_busy(dev);
> +       pm_runtime_put_autosuspend(dev);
> +

Similar comments as above.

> +       return ret;
> +}
> +
>  static int sdhci_esdhc_runtime_suspend(struct device *dev)
>  {
>         struct sdhci_host *host = dev_get_drvdata(dev);
> @@ -1154,7 +1180,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
>  #endif
>
>  static const struct dev_pm_ops sdhci_esdhc_pmops = {
> -       SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, sdhci_pltfm_resume)
> +       SET_SYSTEM_SLEEP_PM_OPS(sdhci_esdhc_suspend, sdhci_esdhc_resume)
>         SET_RUNTIME_PM_OPS(sdhci_esdhc_runtime_suspend,
>                                 sdhci_esdhc_runtime_resume, NULL)
>  };
> --
> 2.3.3
>

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] mmc: sdhci-esdhc-imx: fix abort due to missing runtime PM
  2015-05-06 12:07   ` Ulf Hansson
@ 2015-05-06 20:23     ` Stefan Agner
  -1 siblings, 0 replies; 10+ messages in thread
From: Stefan Agner @ 2015-05-06 20:23 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Chris Ball, Anton Vorontsov, Russell King, Dong Aisheng,
	Shawn Guo, linux-mmc, linux-arm-kernel, linux-kernel

On 2015-05-06 14:07, Ulf Hansson wrote:
> On 30 March 2015 at 13:37, Stefan Agner <stefan@agner.ch> wrote:
>> When entering suspend while the device is in runtime PM, the
>> sdhci_(suspend|resume)_host function are called with disabled clocks.
>> Since this functions access the SDHC host registers, this leads to an
>> external abort on Vybrid SoC:
>>
>> [   37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000
>> [   37.780304] Internal error: : 1c06 [#1] ARM
>> [   37.784670] Modules linked in:
>> [   37.787908] CPU: 0 PID: 428 Comm: sh Not tainted 3.18.0-rc5-00119-geefd097-dirty #1540
>> [   37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000
>> [   37.801785] PC is at esdhc_writel_le+0x40/0xec
>> [   37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4
>> [   37.811877] pc : [<803f0584>]    lr : [<803eaaa0>]    psr: 400f0013
>> [   37.811877] sp : 8ca6dd28  ip : 00000001  fp : 8ca6dd3c
>> [   37.823766] r10: 807a233c  r9 : 00000000  r8 : 8e8b7210
>> [   37.829194] r7 : 802d8a08  r6 : 8082e928  r5 : 00000000  r4 : 00000002
>> [   37.835974] r3 : 8ea34e90  r2 : 00000038  r1 : 00000000  r0 : 8ea32ac0
>> ...
>>
>> Clocks need to be enabled to access the registers. Fix the issue by
>> add driver specific implementation of suspend/resume functions which
>> take care of clocks using runtime PM API.
>>
>> Signed-off-by: Stefan Agner <stefan@agner.ch>
> 
> Hi Stefan,
> 
> Sorry for the delay.
> 
> Indeed sdhci seems to have some issues when combining runtime PM and system PM.
> 
>> ---
>> The first version of this patch was part of a patchset sent back in
>> december. While the second patch of the patchset back then is invalid,
>> this fix is required to avoid the abort when switching into suspend
>> mode on Vybrid SoC.
>>
>> During review of this patch I realized that my proposed solution to
>> fix this in the suspend/resume functions in sdhci-pltfm.c is not a
>> good idea since a lot of drivers use this functions without using the
>> runtime PM APIs.
>>
>> Changes since v1:
>> - Create new sdhci_esdhc_(suspend|resume) functions in favor of adding a
>>   hard requirement for runtime PM on SDHC platform implementations
>>
>>  drivers/mmc/host/sdhci-esdhc-imx.c | 28 +++++++++++++++++++++++++++-
>>  1 file changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
>> index 10ef824..84b3365 100644
>> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
>> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
>> @@ -1119,6 +1119,32 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
>>  }
>>
>>  #ifdef CONFIG_PM
>> +static int sdhci_esdhc_suspend(struct device *dev)
>> +{
>> +       int ret;
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       pm_runtime_get_sync(dev);
> 
> This is indeed needed, since else it isn't safe to invoke sdhci_suspend_host().
> 
>> +       ret = sdhci_suspend_host(host);
>> +       pm_runtime_mark_last_busy(dev);
>> +       pm_runtime_put_autosuspend(dev);
> 
> The problem is, that this wont do what you think I believe.
> 
> The device will be kept runtime PM resumed, since the PM core has
> increased a runtime PM reference count for your device, in the
> ->prepare() phase (pm_runtime_get_noresume()).

Which ->prepare() phase do you mean exactly? I don't see where
pm_runtime_get_noresume gets from this driver.

> 
> Potentially pm_runtime_force_suspend() could help you accomplish what you want.

I copied the implementation from the PXA driver (sdhci-pxav3.c), is the
driver suffering the same issue?

--
Stefan

> 
>> +
>> +       return ret;
>> +}
>> +
>> +static int sdhci_esdhc_resume(struct device *dev)
>> +{
>> +       int ret;
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       pm_runtime_get_sync(dev);
>> +       ret = sdhci_resume_host(host);
>> +       pm_runtime_mark_last_busy(dev);
>> +       pm_runtime_put_autosuspend(dev);
>> +
> 
> Similar comments as above.
> 
>> +       return ret;
>> +}
>> +
>>  static int sdhci_esdhc_runtime_suspend(struct device *dev)
>>  {
>>         struct sdhci_host *host = dev_get_drvdata(dev);
>> @@ -1154,7 +1180,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
>>  #endif
>>
>>  static const struct dev_pm_ops sdhci_esdhc_pmops = {
>> -       SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, sdhci_pltfm_resume)
>> +       SET_SYSTEM_SLEEP_PM_OPS(sdhci_esdhc_suspend, sdhci_esdhc_resume)
>>         SET_RUNTIME_PM_OPS(sdhci_esdhc_runtime_suspend,
>>                                 sdhci_esdhc_runtime_resume, NULL)
>>  };
>> --
>> 2.3.3
>>
> 
> Kind regards
> Uffe



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2] mmc: sdhci-esdhc-imx: fix abort due to missing runtime PM
@ 2015-05-06 20:23     ` Stefan Agner
  0 siblings, 0 replies; 10+ messages in thread
From: Stefan Agner @ 2015-05-06 20:23 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015-05-06 14:07, Ulf Hansson wrote:
> On 30 March 2015 at 13:37, Stefan Agner <stefan@agner.ch> wrote:
>> When entering suspend while the device is in runtime PM, the
>> sdhci_(suspend|resume)_host function are called with disabled clocks.
>> Since this functions access the SDHC host registers, this leads to an
>> external abort on Vybrid SoC:
>>
>> [   37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000
>> [   37.780304] Internal error: : 1c06 [#1] ARM
>> [   37.784670] Modules linked in:
>> [   37.787908] CPU: 0 PID: 428 Comm: sh Not tainted 3.18.0-rc5-00119-geefd097-dirty #1540
>> [   37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000
>> [   37.801785] PC is at esdhc_writel_le+0x40/0xec
>> [   37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4
>> [   37.811877] pc : [<803f0584>]    lr : [<803eaaa0>]    psr: 400f0013
>> [   37.811877] sp : 8ca6dd28  ip : 00000001  fp : 8ca6dd3c
>> [   37.823766] r10: 807a233c  r9 : 00000000  r8 : 8e8b7210
>> [   37.829194] r7 : 802d8a08  r6 : 8082e928  r5 : 00000000  r4 : 00000002
>> [   37.835974] r3 : 8ea34e90  r2 : 00000038  r1 : 00000000  r0 : 8ea32ac0
>> ...
>>
>> Clocks need to be enabled to access the registers. Fix the issue by
>> add driver specific implementation of suspend/resume functions which
>> take care of clocks using runtime PM API.
>>
>> Signed-off-by: Stefan Agner <stefan@agner.ch>
> 
> Hi Stefan,
> 
> Sorry for the delay.
> 
> Indeed sdhci seems to have some issues when combining runtime PM and system PM.
> 
>> ---
>> The first version of this patch was part of a patchset sent back in
>> december. While the second patch of the patchset back then is invalid,
>> this fix is required to avoid the abort when switching into suspend
>> mode on Vybrid SoC.
>>
>> During review of this patch I realized that my proposed solution to
>> fix this in the suspend/resume functions in sdhci-pltfm.c is not a
>> good idea since a lot of drivers use this functions without using the
>> runtime PM APIs.
>>
>> Changes since v1:
>> - Create new sdhci_esdhc_(suspend|resume) functions in favor of adding a
>>   hard requirement for runtime PM on SDHC platform implementations
>>
>>  drivers/mmc/host/sdhci-esdhc-imx.c | 28 +++++++++++++++++++++++++++-
>>  1 file changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
>> index 10ef824..84b3365 100644
>> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
>> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
>> @@ -1119,6 +1119,32 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
>>  }
>>
>>  #ifdef CONFIG_PM
>> +static int sdhci_esdhc_suspend(struct device *dev)
>> +{
>> +       int ret;
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       pm_runtime_get_sync(dev);
> 
> This is indeed needed, since else it isn't safe to invoke sdhci_suspend_host().
> 
>> +       ret = sdhci_suspend_host(host);
>> +       pm_runtime_mark_last_busy(dev);
>> +       pm_runtime_put_autosuspend(dev);
> 
> The problem is, that this wont do what you think I believe.
> 
> The device will be kept runtime PM resumed, since the PM core has
> increased a runtime PM reference count for your device, in the
> ->prepare() phase (pm_runtime_get_noresume()).

Which ->prepare() phase do you mean exactly? I don't see where
pm_runtime_get_noresume gets from this driver.

> 
> Potentially pm_runtime_force_suspend() could help you accomplish what you want.

I copied the implementation from the PXA driver (sdhci-pxav3.c), is the
driver suffering the same issue?

--
Stefan

> 
>> +
>> +       return ret;
>> +}
>> +
>> +static int sdhci_esdhc_resume(struct device *dev)
>> +{
>> +       int ret;
>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +       pm_runtime_get_sync(dev);
>> +       ret = sdhci_resume_host(host);
>> +       pm_runtime_mark_last_busy(dev);
>> +       pm_runtime_put_autosuspend(dev);
>> +
> 
> Similar comments as above.
> 
>> +       return ret;
>> +}
>> +
>>  static int sdhci_esdhc_runtime_suspend(struct device *dev)
>>  {
>>         struct sdhci_host *host = dev_get_drvdata(dev);
>> @@ -1154,7 +1180,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
>>  #endif
>>
>>  static const struct dev_pm_ops sdhci_esdhc_pmops = {
>> -       SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, sdhci_pltfm_resume)
>> +       SET_SYSTEM_SLEEP_PM_OPS(sdhci_esdhc_suspend, sdhci_esdhc_resume)
>>         SET_RUNTIME_PM_OPS(sdhci_esdhc_runtime_suspend,
>>                                 sdhci_esdhc_runtime_resume, NULL)
>>  };
>> --
>> 2.3.3
>>
> 
> Kind regards
> Uffe

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] mmc: sdhci-esdhc-imx: fix abort due to missing runtime PM
  2015-05-06 20:23     ` Stefan Agner
  (?)
@ 2015-05-11  9:40       ` Ulf Hansson
  -1 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2015-05-11  9:40 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Chris Ball, Anton Vorontsov, Russell King, Dong Aisheng,
	Shawn Guo, linux-mmc, linux-arm-kernel, linux-kernel

On 6 May 2015 at 22:23, Stefan Agner <stefan@agner.ch> wrote:
> On 2015-05-06 14:07, Ulf Hansson wrote:
>> On 30 March 2015 at 13:37, Stefan Agner <stefan@agner.ch> wrote:
>>> When entering suspend while the device is in runtime PM, the
>>> sdhci_(suspend|resume)_host function are called with disabled clocks.
>>> Since this functions access the SDHC host registers, this leads to an
>>> external abort on Vybrid SoC:
>>>
>>> [   37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000
>>> [   37.780304] Internal error: : 1c06 [#1] ARM
>>> [   37.784670] Modules linked in:
>>> [   37.787908] CPU: 0 PID: 428 Comm: sh Not tainted 3.18.0-rc5-00119-geefd097-dirty #1540
>>> [   37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000
>>> [   37.801785] PC is at esdhc_writel_le+0x40/0xec
>>> [   37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4
>>> [   37.811877] pc : [<803f0584>]    lr : [<803eaaa0>]    psr: 400f0013
>>> [   37.811877] sp : 8ca6dd28  ip : 00000001  fp : 8ca6dd3c
>>> [   37.823766] r10: 807a233c  r9 : 00000000  r8 : 8e8b7210
>>> [   37.829194] r7 : 802d8a08  r6 : 8082e928  r5 : 00000000  r4 : 00000002
>>> [   37.835974] r3 : 8ea34e90  r2 : 00000038  r1 : 00000000  r0 : 8ea32ac0
>>> ...
>>>
>>> Clocks need to be enabled to access the registers. Fix the issue by
>>> add driver specific implementation of suspend/resume functions which
>>> take care of clocks using runtime PM API.
>>>
>>> Signed-off-by: Stefan Agner <stefan@agner.ch>
>>
>> Hi Stefan,
>>
>> Sorry for the delay.
>>
>> Indeed sdhci seems to have some issues when combining runtime PM and system PM.
>>
>>> ---
>>> The first version of this patch was part of a patchset sent back in
>>> december. While the second patch of the patchset back then is invalid,
>>> this fix is required to avoid the abort when switching into suspend
>>> mode on Vybrid SoC.
>>>
>>> During review of this patch I realized that my proposed solution to
>>> fix this in the suspend/resume functions in sdhci-pltfm.c is not a
>>> good idea since a lot of drivers use this functions without using the
>>> runtime PM APIs.
>>>
>>> Changes since v1:
>>> - Create new sdhci_esdhc_(suspend|resume) functions in favor of adding a
>>>   hard requirement for runtime PM on SDHC platform implementations
>>>
>>>  drivers/mmc/host/sdhci-esdhc-imx.c | 28 +++++++++++++++++++++++++++-
>>>  1 file changed, 27 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
>>> index 10ef824..84b3365 100644
>>> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
>>> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
>>> @@ -1119,6 +1119,32 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
>>>  }
>>>
>>>  #ifdef CONFIG_PM
>>> +static int sdhci_esdhc_suspend(struct device *dev)
>>> +{
>>> +       int ret;
>>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>>> +
>>> +       pm_runtime_get_sync(dev);
>>
>> This is indeed needed, since else it isn't safe to invoke sdhci_suspend_host().
>>
>>> +       ret = sdhci_suspend_host(host);
>>> +       pm_runtime_mark_last_busy(dev);
>>> +       pm_runtime_put_autosuspend(dev);
>>
>> The problem is, that this wont do what you think I believe.
>>
>> The device will be kept runtime PM resumed, since the PM core has
>> increased a runtime PM reference count for your device, in the
>> ->prepare() phase (pm_runtime_get_noresume()).
>
> Which ->prepare() phase do you mean exactly? I don't see where
> pm_runtime_get_noresume gets from this driver.

It's not this driver that does it, it's the PM core.

drivers/base/power/main.c

dpm_prepare()
  -> device_prepare()
     -> pm_runtime_get_noresume()

>
>>
>> Potentially pm_runtime_force_suspend() could help you accomplish what you want.
>
> I copied the implementation from the PXA driver (sdhci-pxav3.c), is the
> driver suffering the same issue?

Yes!

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] mmc: sdhci-esdhc-imx: fix abort due to missing runtime PM
@ 2015-05-11  9:40       ` Ulf Hansson
  0 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2015-05-11  9:40 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Chris Ball, Anton Vorontsov, Russell King, Dong Aisheng,
	Shawn Guo, linux-mmc, linux-arm-kernel, linux-kernel

On 6 May 2015 at 22:23, Stefan Agner <stefan@agner.ch> wrote:
> On 2015-05-06 14:07, Ulf Hansson wrote:
>> On 30 March 2015 at 13:37, Stefan Agner <stefan@agner.ch> wrote:
>>> When entering suspend while the device is in runtime PM, the
>>> sdhci_(suspend|resume)_host function are called with disabled clocks.
>>> Since this functions access the SDHC host registers, this leads to an
>>> external abort on Vybrid SoC:
>>>
>>> [   37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000
>>> [   37.780304] Internal error: : 1c06 [#1] ARM
>>> [   37.784670] Modules linked in:
>>> [   37.787908] CPU: 0 PID: 428 Comm: sh Not tainted 3.18.0-rc5-00119-geefd097-dirty #1540
>>> [   37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000
>>> [   37.801785] PC is at esdhc_writel_le+0x40/0xec
>>> [   37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4
>>> [   37.811877] pc : [<803f0584>]    lr : [<803eaaa0>]    psr: 400f0013
>>> [   37.811877] sp : 8ca6dd28  ip : 00000001  fp : 8ca6dd3c
>>> [   37.823766] r10: 807a233c  r9 : 00000000  r8 : 8e8b7210
>>> [   37.829194] r7 : 802d8a08  r6 : 8082e928  r5 : 00000000  r4 : 00000002
>>> [   37.835974] r3 : 8ea34e90  r2 : 00000038  r1 : 00000000  r0 : 8ea32ac0
>>> ...
>>>
>>> Clocks need to be enabled to access the registers. Fix the issue by
>>> add driver specific implementation of suspend/resume functions which
>>> take care of clocks using runtime PM API.
>>>
>>> Signed-off-by: Stefan Agner <stefan@agner.ch>
>>
>> Hi Stefan,
>>
>> Sorry for the delay.
>>
>> Indeed sdhci seems to have some issues when combining runtime PM and system PM.
>>
>>> ---
>>> The first version of this patch was part of a patchset sent back in
>>> december. While the second patch of the patchset back then is invalid,
>>> this fix is required to avoid the abort when switching into suspend
>>> mode on Vybrid SoC.
>>>
>>> During review of this patch I realized that my proposed solution to
>>> fix this in the suspend/resume functions in sdhci-pltfm.c is not a
>>> good idea since a lot of drivers use this functions without using the
>>> runtime PM APIs.
>>>
>>> Changes since v1:
>>> - Create new sdhci_esdhc_(suspend|resume) functions in favor of adding a
>>>   hard requirement for runtime PM on SDHC platform implementations
>>>
>>>  drivers/mmc/host/sdhci-esdhc-imx.c | 28 +++++++++++++++++++++++++++-
>>>  1 file changed, 27 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
>>> index 10ef824..84b3365 100644
>>> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
>>> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
>>> @@ -1119,6 +1119,32 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
>>>  }
>>>
>>>  #ifdef CONFIG_PM
>>> +static int sdhci_esdhc_suspend(struct device *dev)
>>> +{
>>> +       int ret;
>>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>>> +
>>> +       pm_runtime_get_sync(dev);
>>
>> This is indeed needed, since else it isn't safe to invoke sdhci_suspend_host().
>>
>>> +       ret = sdhci_suspend_host(host);
>>> +       pm_runtime_mark_last_busy(dev);
>>> +       pm_runtime_put_autosuspend(dev);
>>
>> The problem is, that this wont do what you think I believe.
>>
>> The device will be kept runtime PM resumed, since the PM core has
>> increased a runtime PM reference count for your device, in the
>> ->prepare() phase (pm_runtime_get_noresume()).
>
> Which ->prepare() phase do you mean exactly? I don't see where
> pm_runtime_get_noresume gets from this driver.

It's not this driver that does it, it's the PM core.

drivers/base/power/main.c

dpm_prepare()
  -> device_prepare()
     -> pm_runtime_get_noresume()

>
>>
>> Potentially pm_runtime_force_suspend() could help you accomplish what you want.
>
> I copied the implementation from the PXA driver (sdhci-pxav3.c), is the
> driver suffering the same issue?

Yes!

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2] mmc: sdhci-esdhc-imx: fix abort due to missing runtime PM
@ 2015-05-11  9:40       ` Ulf Hansson
  0 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2015-05-11  9:40 UTC (permalink / raw)
  To: linux-arm-kernel

On 6 May 2015 at 22:23, Stefan Agner <stefan@agner.ch> wrote:
> On 2015-05-06 14:07, Ulf Hansson wrote:
>> On 30 March 2015 at 13:37, Stefan Agner <stefan@agner.ch> wrote:
>>> When entering suspend while the device is in runtime PM, the
>>> sdhci_(suspend|resume)_host function are called with disabled clocks.
>>> Since this functions access the SDHC host registers, this leads to an
>>> external abort on Vybrid SoC:
>>>
>>> [   37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000
>>> [   37.780304] Internal error: : 1c06 [#1] ARM
>>> [   37.784670] Modules linked in:
>>> [   37.787908] CPU: 0 PID: 428 Comm: sh Not tainted 3.18.0-rc5-00119-geefd097-dirty #1540
>>> [   37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000
>>> [   37.801785] PC is at esdhc_writel_le+0x40/0xec
>>> [   37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4
>>> [   37.811877] pc : [<803f0584>]    lr : [<803eaaa0>]    psr: 400f0013
>>> [   37.811877] sp : 8ca6dd28  ip : 00000001  fp : 8ca6dd3c
>>> [   37.823766] r10: 807a233c  r9 : 00000000  r8 : 8e8b7210
>>> [   37.829194] r7 : 802d8a08  r6 : 8082e928  r5 : 00000000  r4 : 00000002
>>> [   37.835974] r3 : 8ea34e90  r2 : 00000038  r1 : 00000000  r0 : 8ea32ac0
>>> ...
>>>
>>> Clocks need to be enabled to access the registers. Fix the issue by
>>> add driver specific implementation of suspend/resume functions which
>>> take care of clocks using runtime PM API.
>>>
>>> Signed-off-by: Stefan Agner <stefan@agner.ch>
>>
>> Hi Stefan,
>>
>> Sorry for the delay.
>>
>> Indeed sdhci seems to have some issues when combining runtime PM and system PM.
>>
>>> ---
>>> The first version of this patch was part of a patchset sent back in
>>> december. While the second patch of the patchset back then is invalid,
>>> this fix is required to avoid the abort when switching into suspend
>>> mode on Vybrid SoC.
>>>
>>> During review of this patch I realized that my proposed solution to
>>> fix this in the suspend/resume functions in sdhci-pltfm.c is not a
>>> good idea since a lot of drivers use this functions without using the
>>> runtime PM APIs.
>>>
>>> Changes since v1:
>>> - Create new sdhci_esdhc_(suspend|resume) functions in favor of adding a
>>>   hard requirement for runtime PM on SDHC platform implementations
>>>
>>>  drivers/mmc/host/sdhci-esdhc-imx.c | 28 +++++++++++++++++++++++++++-
>>>  1 file changed, 27 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
>>> index 10ef824..84b3365 100644
>>> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
>>> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
>>> @@ -1119,6 +1119,32 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
>>>  }
>>>
>>>  #ifdef CONFIG_PM
>>> +static int sdhci_esdhc_suspend(struct device *dev)
>>> +{
>>> +       int ret;
>>> +       struct sdhci_host *host = dev_get_drvdata(dev);
>>> +
>>> +       pm_runtime_get_sync(dev);
>>
>> This is indeed needed, since else it isn't safe to invoke sdhci_suspend_host().
>>
>>> +       ret = sdhci_suspend_host(host);
>>> +       pm_runtime_mark_last_busy(dev);
>>> +       pm_runtime_put_autosuspend(dev);
>>
>> The problem is, that this wont do what you think I believe.
>>
>> The device will be kept runtime PM resumed, since the PM core has
>> increased a runtime PM reference count for your device, in the
>> ->prepare() phase (pm_runtime_get_noresume()).
>
> Which ->prepare() phase do you mean exactly? I don't see where
> pm_runtime_get_noresume gets from this driver.

It's not this driver that does it, it's the PM core.

drivers/base/power/main.c

dpm_prepare()
  -> device_prepare()
     -> pm_runtime_get_noresume()

>
>>
>> Potentially pm_runtime_force_suspend() could help you accomplish what you want.
>
> I copied the implementation from the PXA driver (sdhci-pxav3.c), is the
> driver suffering the same issue?

Yes!

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-05-11  9:40 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-30 11:37 [PATCH v2] mmc: sdhci-esdhc-imx: fix abort due to missing runtime PM Stefan Agner
2015-03-30 11:37 ` Stefan Agner
2015-05-06 12:07 ` Ulf Hansson
2015-05-06 12:07   ` Ulf Hansson
2015-05-06 12:07   ` Ulf Hansson
2015-05-06 20:23   ` Stefan Agner
2015-05-06 20:23     ` Stefan Agner
2015-05-11  9:40     ` Ulf Hansson
2015-05-11  9:40       ` Ulf Hansson
2015-05-11  9:40       ` Ulf Hansson

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.