All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] PM / Domains: Fix genpd to deal with drivers returning 1 from ->prepare()
@ 2017-11-08  9:11 Ulf Hansson
  2017-11-08 12:42 ` Rafael J. Wysocki
  0 siblings, 1 reply; 2+ messages in thread
From: Ulf Hansson @ 2017-11-08  9:11 UTC (permalink / raw)
  To: Rafael J . Wysocki, linux-pm
  Cc: Kevin Hilman, Viresh Kumar, Geert Uytterhoeven, Ulf Hansson

During system-wide PM, genpd relies on its PM callbacks to be invoked for
all its attached devices, as to deal with powering off/on the PM domain. In
other words, genpd is not compatible with the direct_complete path, if
executed by the PM core for any of its attached devices.

However, when genpd's ->prepare() callback invokes pm_generic_prepare(), it
does not take into account that it may return 1. Instead it treats that as
an error internally and expects the PM core to abort the prepare phase and
roll back. This leads to genpd not properly powering on/off the PM domain,
because its internal counters gets wrongly balanced.

To fix the behaviour, allow drivers to return 1 from their ->prepare()
callbacks, but let's return 0 from genpd's ->prepare() callback in such
case, as that prevents the PM core from running the direct_complete path
for the device.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/base/power/domain.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 24e39ce..0c80bea 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1008,7 +1008,7 @@ static int genpd_prepare(struct device *dev)
 	genpd_unlock(genpd);
 
 	ret = pm_generic_prepare(dev);
-	if (ret) {
+	if (ret < 0) {
 		genpd_lock(genpd);
 
 		genpd->prepared_count--;
@@ -1016,7 +1016,8 @@ static int genpd_prepare(struct device *dev)
 		genpd_unlock(genpd);
 	}
 
-	return ret;
+	/* Never return 1, as genpd don't cope with the direct_complete path. */
+	return ret >= 0 ? 0 : ret;
 }
 
 /**
-- 
2.7.4

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

* Re: [PATCH] PM / Domains: Fix genpd to deal with drivers returning 1 from ->prepare()
  2017-11-08  9:11 [PATCH] PM / Domains: Fix genpd to deal with drivers returning 1 from ->prepare() Ulf Hansson
@ 2017-11-08 12:42 ` Rafael J. Wysocki
  0 siblings, 0 replies; 2+ messages in thread
From: Rafael J. Wysocki @ 2017-11-08 12:42 UTC (permalink / raw)
  To: Ulf Hansson; +Cc: linux-pm, Kevin Hilman, Viresh Kumar, Geert Uytterhoeven

On Wednesday, November 8, 2017 10:11:02 AM CET Ulf Hansson wrote:
> During system-wide PM, genpd relies on its PM callbacks to be invoked for
> all its attached devices, as to deal with powering off/on the PM domain. In
> other words, genpd is not compatible with the direct_complete path, if
> executed by the PM core for any of its attached devices.
> 
> However, when genpd's ->prepare() callback invokes pm_generic_prepare(), it
> does not take into account that it may return 1. Instead it treats that as
> an error internally and expects the PM core to abort the prepare phase and
> roll back. This leads to genpd not properly powering on/off the PM domain,
> because its internal counters gets wrongly balanced.
> 
> To fix the behaviour, allow drivers to return 1 from their ->prepare()
> callbacks, but let's return 0 from genpd's ->prepare() callback in such
> case, as that prevents the PM core from running the direct_complete path
> for the device.
> 
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>  drivers/base/power/domain.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index 24e39ce..0c80bea 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -1008,7 +1008,7 @@ static int genpd_prepare(struct device *dev)
>  	genpd_unlock(genpd);
>  
>  	ret = pm_generic_prepare(dev);
> -	if (ret) {
> +	if (ret < 0) {
>  		genpd_lock(genpd);
>  
>  		genpd->prepared_count--;
> @@ -1016,7 +1016,8 @@ static int genpd_prepare(struct device *dev)
>  		genpd_unlock(genpd);
>  	}
>  
> -	return ret;
> +	/* Never return 1, as genpd don't cope with the direct_complete path. */
> +	return ret >= 0 ? 0 : ret;
>  }
>  
>  /**
> 

Queued up for 4.15, thanks!

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

end of thread, other threads:[~2017-11-08 12:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-08  9:11 [PATCH] PM / Domains: Fix genpd to deal with drivers returning 1 from ->prepare() Ulf Hansson
2017-11-08 12:42 ` Rafael J. Wysocki

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.