| From d84434c51963463394ca4902afd4eca7f72c6ed8 Mon Sep 17 00:00:00 2001 |
| From: Ulf Hansson <ulf.hansson@linaro.org> |
| Date: Wed, 10 Apr 2019 11:55:16 +0200 |
| Subject: PM / core: Propagate dev->power.wakeup_path when no callbacks |
| |
| [ Upstream commit dc351d4c5f4fe4d0f274d6d660227be0c3a03317 ] |
| |
| The dev->power.direct_complete flag may become set in device_prepare() in |
| case the device don't have any PM callbacks (dev->power.no_pm_callbacks is |
| set). This leads to a broken behaviour, when there is child having wakeup |
| enabled and relies on its parent to be used in the wakeup path. |
| |
| More precisely, when the direct complete path becomes selected for the |
| child in __device_suspend(), the propagation of the dev->power.wakeup_path |
| becomes skipped as well. |
| |
| Let's address this problem, by checking if the device is a part the wakeup |
| path or has wakeup enabled, then prevent the direct complete path from |
| being used. |
| |
| Reported-by: Loic Pallardy <loic.pallardy@st.com> |
| Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> |
| [ rjw: Comment cleanup ] |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/base/power/main.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c |
| index f80d298de3fa4..8ad20ed0cb7c3 100644 |
| --- a/drivers/base/power/main.c |
| +++ b/drivers/base/power/main.c |
| @@ -1747,6 +1747,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) |
| if (dev->power.syscore) |
| goto Complete; |
| |
| + /* Avoid direct_complete to let wakeup_path propagate. */ |
| + if (device_may_wakeup(dev) || dev->power.wakeup_path) |
| + dev->power.direct_complete = false; |
| + |
| if (dev->power.direct_complete) { |
| if (pm_runtime_status_suspended(dev)) { |
| pm_runtime_disable(dev); |
| -- |
| 2.20.1 |
| |