aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-10-04 05:08:12 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-10-04 13:39:31 -0400
commit69e445ab8b66a9f30519842ef18be555d3ee9b51 (patch)
tree115eba75d4db85e1a78a63b614bf4df9b94c815d
parent17b57b1883c1285f3d0dc2266e8f79286a7bef38 (diff)
PM / core: Clear the direct_complete flag on errors
If __device_suspend() runs asynchronously (in which case the device passed to it is in dpm_suspended_list at that point) and it returns early on an error or pending wakeup, and the power.direct_complete flag has been set for the device already, the subsequent device_resume() will be confused by that and it will call pm_runtime_enable() incorrectly, as runtime PM has not been disabled for the device by __device_suspend(). To avoid that, clear power.direct_complete if __device_suspend() is not going to disable runtime PM for the device before returning. Fixes: aae4518b3124 (PM / sleep: Mechanism to avoid resuming runtime-suspended devices unnecessarily) Reported-by: Al Cooper <alcooperx@gmail.com> Tested-by: Al Cooper <alcooperx@gmail.com> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Cc: 3.16+ <stable@vger.kernel.org> # 3.16+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/base/power/main.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 3f68e2919dc5..a690fd400260 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1713,8 +1713,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1713 1713
1714 dpm_wait_for_subordinate(dev, async); 1714 dpm_wait_for_subordinate(dev, async);
1715 1715
1716 if (async_error) 1716 if (async_error) {
1717 dev->power.direct_complete = false;
1717 goto Complete; 1718 goto Complete;
1719 }
1718 1720
1719 /* 1721 /*
1720 * If a device configured to wake up the system from sleep states 1722 * If a device configured to wake up the system from sleep states
@@ -1726,6 +1728,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1726 pm_wakeup_event(dev, 0); 1728 pm_wakeup_event(dev, 0);
1727 1729
1728 if (pm_wakeup_pending()) { 1730 if (pm_wakeup_pending()) {
1731 dev->power.direct_complete = false;
1729 async_error = -EBUSY; 1732 async_error = -EBUSY;
1730 goto Complete; 1733 goto Complete;
1731 } 1734 }