diff options
-rw-r--r-- | drivers/base/power/main.c | 29 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 17 |
2 files changed, 18 insertions, 28 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 2700f2e4066f..077b9756fd8f 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -565,7 +565,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) pm_callback_t callback = NULL; char *info = NULL; int error = 0; - bool put = false; TRACE_DEVICE(dev); TRACE_RESUME(0); @@ -583,7 +582,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) goto Unlock; pm_runtime_enable(dev); - put = true; if (dev->pm_domain) { info = "power domain "; @@ -636,9 +634,6 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) TRACE_RESUME(error); - if (put) - pm_runtime_put_sync(dev); - return error; } @@ -749,6 +744,8 @@ static void device_complete(struct device *dev, pm_message_t state) } device_unlock(dev); + + pm_runtime_put_sync(dev); } /** @@ -1043,12 +1040,16 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) if (async_error) goto Complete; - pm_runtime_get_noresume(dev); + /* + * If a device configured to wake up the system from sleep states + * has been suspended at run time and there's a resume request pending + * for it, this is equivalent to the device signaling wakeup, so the + * system suspend operation should be aborted. + */ if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) pm_wakeup_event(dev, 0); if (pm_wakeup_pending()) { - pm_runtime_put_sync(dev); async_error = -EBUSY; goto Complete; } @@ -1111,12 +1112,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) Complete: complete_all(&dev->power.completion); - if (error) { - pm_runtime_put_sync(dev); + if (error) async_error = error; - } else if (dev->power.is_suspended) { + else if (dev->power.is_suspended) __pm_runtime_disable(dev, false); - } return error; } @@ -1209,6 +1208,14 @@ static int device_prepare(struct device *dev, pm_message_t state) char *info = NULL; int error = 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 + * block runtime suspend here, during the prepare phase, and allow + * it again during the complete phase. + */ + pm_runtime_get_noresume(dev); + device_lock(dev); dev->power.wakeup_path = device_may_wakeup(dev); diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 185be3703343..51cd90bcdd4c 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -624,21 +624,6 @@ static int pci_pm_prepare(struct device *dev) int error = 0; /* - * If a PCI device configured to wake up the system from sleep states - * has been suspended at run time and there's a resume request pending - * for it, this is equivalent to the device signaling wakeup, so the - * system suspend operation should be aborted. - */ - pm_runtime_get_noresume(dev); - if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) - pm_wakeup_event(dev, 0); - - if (pm_wakeup_pending()) { - pm_runtime_put_sync(dev); - return -EBUSY; - } - - /* * PCI devices suspended at run time need to be resumed at this * point, because in general it is necessary to reconfigure them for * system suspend. Namely, if the device is supposed to wake up the @@ -661,8 +646,6 @@ static void pci_pm_complete(struct device *dev) if (drv && drv->pm && drv->pm->complete) drv->pm->complete(dev); - - pm_runtime_put_sync(dev); } #else /* !CONFIG_PM_SLEEP */ |