PM: sleep: Do not let "syscore" devices runtime-suspend during system transitions
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 22 Oct 2021 12:58:23 +0000 (14:58 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Nov 2021 18:15:59 +0000 (19:15 +0100)
commit 928265e3601cde78c7e0a3e518a93b27defed3b1 upstream.

There is no reason to allow "syscore" devices to runtime-suspend
during system-wide PM transitions, because they are subject to the
same possible failure modes as any other devices in that respect.

Accordingly, change device_prepare() and device_complete() to call
pm_runtime_get_noresume() and pm_runtime_put(), respectively, for
"syscore" devices too.

Fixes: 057d51a1268f ("Merge branch 'pm-sleep'")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: 3.10+ <stable@vger.kernel.org> # 3.10+
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/base/power/main.c

index cbea78e..fca6eab 100644 (file)
@@ -1051,7 +1051,7 @@ static void device_complete(struct device *dev, pm_message_t state)
        const char *info = NULL;
 
        if (dev->power.syscore)
-               return;
+               goto out;
 
        device_lock(dev);
 
@@ -1081,6 +1081,7 @@ static void device_complete(struct device *dev, pm_message_t state)
 
        device_unlock(dev);
 
+out:
        pm_runtime_put(dev);
 }
 
@@ -1794,9 +1795,6 @@ static int device_prepare(struct device *dev, pm_message_t state)
        int (*callback)(struct device *) = NULL;
        int ret = 0;
 
-       if (dev->power.syscore)
-               return 0;
-
        /*
         * If a device's parent goes into runtime suspend at the wrong time,
         * it won't be possible to resume the device.  To prevent this we
@@ -1805,6 +1803,9 @@ static int device_prepare(struct device *dev, pm_message_t state)
         */
        pm_runtime_get_noresume(dev);
 
+       if (dev->power.syscore)
+               return 0;
+
        device_lock(dev);
 
        dev->power.wakeup_path = false;