[RAMEN9610-11180] PM / sleep: fix unbalanced pm_runtime_enable while aborting suspend
authorJeonghoon Jang <jnghn.jang@samsung.com>
Mon, 21 Jan 2019 08:54:52 +0000 (17:54 +0900)
committerhskang <hs1218.kang@samsung.com>
Tue, 22 Jan 2019 13:09:16 +0000 (22:09 +0900)
The device can go direct to complete at __device_suspend and
device_resume if its driver has no callbacks. In that case,
pm_runtime_enable was called at device_resume without pm_runtime_disable
at __device_suspend when suspend was aborted at __devive_suspend
because of pending wakeups. It causes unbalanced pm_runtime_enable.

Change-Id: Iceec2a72efa7a15673663828e6e692ae6958ab28
Signed-off-by: Jeonghoon Jang <jnghn.jang@samsung.com>
drivers/base/power/main.c
include/linux/pm.h

index e24f6500786e32f0c2a3d585c88975db2cdd85bf..a8d49f2e07596f529d7562d28302e6ee47686c3f 100644 (file)
@@ -820,7 +820,10 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
 
        if (dev->power.direct_complete) {
                /* Match the pm_runtime_disable() in __device_suspend(). */
-               pm_runtime_enable(dev);
+               if (!dev->power.is_suspend_aborted)
+                       pm_runtime_enable(dev);
+               else
+                       dev->power.is_suspend_aborted = false;
                goto Complete;
        }
 
@@ -1481,6 +1484,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
                        MAX_SUSPEND_ABORT_LEN);
                log_suspend_abort_reason(suspend_abort);
                async_error = -EBUSY;
+               if (dev->power.direct_complete)
+                       dev->power.is_suspend_aborted = true;
                goto Complete;
        }
 
index 47ded8aa8a5d5a0b9ec83e0d362c037a26b03b1d..e53ee687ace38f7341727ac481a55f4aeb7fcce6 100644 (file)
@@ -569,6 +569,7 @@ struct dev_pm_info {
        bool                    wakeup_path:1;
        bool                    syscore:1;
        bool                    no_pm_callbacks:1;      /* Owned by the PM core */
+       bool                    is_suspend_aborted:1;   /* Owned by the PM core */
 #else
        unsigned int            should_wakeup:1;
 #endif