aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2017-11-08 04:11:02 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-11-08 06:16:57 -0500
commit5241ab40f6e742f8a1631f8826faf6dc6412b3b5 (patch)
tree5b427f946ad914c48be94926fb4e51d9025b3b1d
parent704d2ce6603f7e40bb607ae9452ff18a4cec701f (diff)
PM / Domains: Fix genpd to deal with drivers returning 1 from ->prepare()
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> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/base/power/domain.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index b914e373a478..47fb71a8066a 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1010,7 +1010,7 @@ static int genpd_prepare(struct device *dev)
1010 genpd_unlock(genpd); 1010 genpd_unlock(genpd);
1011 1011
1012 ret = pm_generic_prepare(dev); 1012 ret = pm_generic_prepare(dev);
1013 if (ret) { 1013 if (ret < 0) {
1014 genpd_lock(genpd); 1014 genpd_lock(genpd);
1015 1015
1016 genpd->prepared_count--; 1016 genpd->prepared_count--;
@@ -1018,7 +1018,8 @@ static int genpd_prepare(struct device *dev)
1018 genpd_unlock(genpd); 1018 genpd_unlock(genpd);
1019 } 1019 }
1020 1020
1021 return ret; 1021 /* Never return 1, as genpd don't cope with the direct_complete path. */
1022 return ret >= 0 ? 0 : ret;
1022} 1023}
1023 1024
1024/** 1025/**