CHROMIUM: PM: Prevent waiting forever on asynchronous suspend after abort
authorMandeep Singh Baines <msb@chromium.org>
Wed, 20 Jun 2012 01:17:55 +0000 (18:17 -0700)
committerGerrit <chrome-bot@google.com>
Thu, 21 Jun 2012 01:31:51 +0000 (18:31 -0700)
__device_suspend() must always send a completion. Otherwise, parent
devices will wait forever.

Commit 1e2ef05b, "PM: Limit race conditions between runtime PM and
system sleep (v2)", introduced a regression by short-circuiting the
complete_all() for certain error cases.

This patch fixes the bug by always signalling a completion.

LKML-Reference: http://lkml.org/lkml/2012/6/20/386

BUG=chromium-os:31972
TEST=Tested by injecting an abort.

Change-Id: Id5ece5e2134d8ae74fbd2a333ddd10c09b015dd4
Signed-off-by: Mandeep Singh Baines <msb@chromium.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Reviewed-on: https://gerrit.chromium.org/gerrit/25774
Reviewed-by: Olof Johansson <olofj@chromium.org>
Reviewed-by: Benson Leung <bleung@chromium.org>
drivers/base/power/main.c

index ca8b2b5..adaa8aa 100644 (file)
@@ -1021,7 +1021,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
        dpm_wait_for_children(dev, async);
 
        if (async_error)
-               return 0;
+               goto Complete;
 
        pm_runtime_get_noresume(dev);
        if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
@@ -1030,7 +1030,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
        if (pm_wakeup_pending()) {
                pm_runtime_put_sync(dev);
                async_error = -EBUSY;
-               return 0;
+               goto Complete;
        }
 
        device_lock(dev);
@@ -1087,6 +1087,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
        }
 
        device_unlock(dev);
+
+ Complete:
        complete_all(&dev->power.completion);
 
        if (error) {