summaryrefslogtreecommitdiffstats
path: root/drivers/base/power/runtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/power/runtime.c')
-rw-r--r--drivers/base/power/runtime.c37
1 files changed, 18 insertions, 19 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 38556f6cc22..5a01ecef4af 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -51,8 +51,6 @@ static int __pm_runtime_idle(struct device *dev)
{
int retval = 0;
- dev_dbg(dev, "__pm_runtime_idle()!\n");
-
if (dev->power.runtime_error)
retval = -EINVAL;
else if (dev->power.idle_notification)
@@ -93,8 +91,6 @@ static int __pm_runtime_idle(struct device *dev)
wake_up_all(&dev->power.wait_queue);
out:
- dev_dbg(dev, "__pm_runtime_idle() returns %d!\n", retval);
-
return retval;
}
@@ -189,6 +185,7 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)
}
dev->power.runtime_status = RPM_SUSPENDING;
+ dev->power.deferred_resume = false;
if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) {
spin_unlock_irq(&dev->power.lock);
@@ -204,7 +201,6 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)
if (retval) {
dev->power.runtime_status = RPM_ACTIVE;
pm_runtime_cancel_pending(dev);
- dev->power.deferred_resume = false;
if (retval == -EAGAIN || retval == -EBUSY) {
notify = true;
@@ -221,7 +217,6 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)
wake_up_all(&dev->power.wait_queue);
if (dev->power.deferred_resume) {
- dev->power.deferred_resume = false;
__pm_runtime_resume(dev, false);
retval = -EAGAIN;
goto out;
@@ -332,11 +327,11 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)
* necessary.
*/
parent = dev->parent;
- spin_unlock_irq(&dev->power.lock);
+ spin_unlock(&dev->power.lock);
pm_runtime_get_noresume(parent);
- spin_lock_irq(&parent->power.lock);
+ spin_lock(&parent->power.lock);
/*
* We can resume if the parent's run-time PM is disabled or it
* is set to ignore children.
@@ -347,9 +342,9 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)
if (parent->power.runtime_status != RPM_ACTIVE)
retval = -EBUSY;
}
- spin_unlock_irq(&parent->power.lock);
+ spin_unlock(&parent->power.lock);
- spin_lock_irq(&dev->power.lock);
+ spin_lock(&dev->power.lock);
if (retval)
goto out;
goto repeat;
@@ -630,6 +625,8 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay)
goto out;
dev->power.timer_expires = jiffies + msecs_to_jiffies(delay);
+ if (!dev->power.timer_expires)
+ dev->power.timer_expires = 1;
mod_timer(&dev->power.suspend_timer, dev->power.timer_expires);
out:
@@ -663,13 +660,17 @@ static int __pm_request_resume(struct device *dev)
pm_runtime_deactivate_timer(dev);
+ if (dev->power.runtime_status == RPM_SUSPENDING) {
+ dev->power.deferred_resume = true;
+ return retval;
+ }
if (dev->power.request_pending) {
/* If non-resume request is pending, we can overtake it. */
dev->power.request = retval ? RPM_REQ_NONE : RPM_REQ_RESUME;
return retval;
- } else if (retval) {
- return retval;
}
+ if (retval)
+ return retval;
dev->power.request = RPM_REQ_RESUME;
dev->power.request_pending = true;
@@ -781,7 +782,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
}
if (parent) {
- spin_lock_irq(&parent->power.lock);
+ spin_lock_nested(&parent->power.lock, SINGLE_DEPTH_NESTING);
/*
* It is invalid to put an active child under a parent that is
@@ -790,14 +791,12 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
*/
if (!parent->power.disable_depth
&& !parent->power.ignore_children
- && parent->power.runtime_status != RPM_ACTIVE) {
+ && parent->power.runtime_status != RPM_ACTIVE)
error = -EBUSY;
- } else {
- if (dev->power.runtime_status == RPM_SUSPENDED)
- atomic_inc(&parent->power.child_count);
- }
+ else if (dev->power.runtime_status == RPM_SUSPENDED)
+ atomic_inc(&parent->power.child_count);
- spin_unlock_irq(&parent->power.lock);
+ spin_unlock(&parent->power.lock);
if (error)
goto out;