[v3,1/4] PM / core: Assign the wakeup_path status flag in __device_prepare()

Message ID 1514909333-4450-2-git-send-email-ulf.hansson@linaro.org
State New
Headers show
Series
  • PM / core: Extend behaviour for wakeup paths
Related show

Commit Message

Ulf Hansson Jan. 2, 2018, 4:08 p.m.
The PM core in the device_prepare() phase, resets the wakeup_path status
flag to the value of device_may_wakeup(). This means if a ->prepare() or a
->suspend() callback for the device would update the device's wakeup
setting, this doesn't become reflected in the wakeup_path status flag.

In general this isn't a problem, because wakeup settings are not supposed
to be changed (via for example calling device_set_wakeup_enable()) during
any system wide suspend/resume phase.  Nevertheless there are some users,
which can be considered as legacy, that don't conform to this behaviour.

These legacy cases should be corrected, however until that is done, let's
address the issue from the PM core, by moving the assignment of the
wakeup_path status flag to the __device_suspend() phase and after the
->suspend() callback has been invoked.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

---
 drivers/base/power/main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

-- 
2.7.4

Comments

Rafael J. Wysocki Jan. 5, 2018, 12:44 p.m. | #1
On Tue, Jan 2, 2018 at 5:08 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> The PM core in the device_prepare() phase, resets the wakeup_path status

> flag to the value of device_may_wakeup(). This means if a ->prepare() or a

> ->suspend() callback for the device would update the device's wakeup

> setting, this doesn't become reflected in the wakeup_path status flag.

>

> In general this isn't a problem, because wakeup settings are not supposed

> to be changed (via for example calling device_set_wakeup_enable()) during

> any system wide suspend/resume phase.  Nevertheless there are some users,

> which can be considered as legacy, that don't conform to this behaviour.

>

> These legacy cases should be corrected, however until that is done, let's

> address the issue from the PM core, by moving the assignment of the

> wakeup_path status flag to the __device_suspend() phase and after the

> ->suspend() callback has been invoked.

>

> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>


I'm queuing this one up with an extra empty line added.

> ---

>  drivers/base/power/main.c | 4 +++-

>  1 file changed, 3 insertions(+), 1 deletion(-)

>

> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c

> index 70398e7..7aeb91d 100644

> --- a/drivers/base/power/main.c

> +++ b/drivers/base/power/main.c

> @@ -1788,6 +1788,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)

>   End:

>         if (!error) {

>                 dev->power.is_suspended = true;

> +               if (device_may_wakeup(dev))

> +                       dev->power.wakeup_path = true;

>                 dpm_propagate_to_parent(dev);

>                 dpm_clear_suppliers_direct_complete(dev);

>         }

> @@ -1912,7 +1914,7 @@ static int device_prepare(struct device *dev, pm_message_t state)

>

>         device_lock(dev);

>

> -       dev->power.wakeup_path = device_may_wakeup(dev);

> +       dev->power.wakeup_path = false;

>

>         if (dev->power.no_pm_callbacks) {

>                 ret = 1;        /* Let device go direct_complete */

> --

> 2.7.4

>

Patch

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 70398e7..7aeb91d 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1788,6 +1788,8 @@  static int __device_suspend(struct device *dev, pm_message_t state, bool async)
  End:
 	if (!error) {
 		dev->power.is_suspended = true;
+		if (device_may_wakeup(dev))
+			dev->power.wakeup_path = true;
 		dpm_propagate_to_parent(dev);
 		dpm_clear_suppliers_direct_complete(dev);
 	}
@@ -1912,7 +1914,7 @@  static int device_prepare(struct device *dev, pm_message_t state)
 
 	device_lock(dev);
 
-	dev->power.wakeup_path = device_may_wakeup(dev);
+	dev->power.wakeup_path = false;
 
 	if (dev->power.no_pm_callbacks) {
 		ret = 1;	/* Let device go direct_complete */