From bab636b921017f0db6e0c2979438f50b898a9808 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 3 Dec 2009 20:21:21 +0100 Subject: PM / Runtime: Fix lockdep warning in __pm_runtime_set_status() Lockdep complains about taking the parent lock in __pm_runtime_set_status(), so mark it as nested. Signed-off-by: Rafael J. Wysocki Reported-by: Alan Stern Cc: stable@kernel.org --- drivers/base/power/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 846d89e3d122..0a4b75f834c0 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -777,7 +777,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) } if (parent) { - spin_lock(&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 -- cgit v1.2.3-59-g8ed1b From 63c94801701abfea21570d3302687ec027ed33e8 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 3 Dec 2009 20:22:34 +0100 Subject: PM / Runtime: Use deferred_resume flag in pm_request_resume This patch (as1307) adds a small optimization to __pm_request_resume(). If the device is currently being suspended, there's no need to queue a work routine to resume it. Setting the deferred_resume flag will suffice. (There's also a minor improvement to the function's code layout: An unnecessary "else" is removed.) Also, the patch clarifies the usage of the deferred_resume flag. It is meaningful only while a suspend is in progress, so it should be cleared just before a suspend starts, not just after one ends. Signed-off-by: Alan Stern Signed-off-by: Rafael J. Wysocki --- drivers/base/power/runtime.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 0a4b75f834c0..6e8577d1f750 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -185,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); @@ -200,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; @@ -217,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; @@ -659,13 +658,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; -- cgit v1.2.3-59-g8ed1b From 0ddf0ed1d47e2d4170fa2989273886a1df66a862 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 3 Dec 2009 21:03:57 +0100 Subject: PM / Runtime: Ensure timer_expires is nonzero in pm_schedule_suspend() The runtime PM core code assumes that dev->power.timer_expires is nonzero when the timer is scheduled, but it may become zero incidentally in pm_schedule_suspend(). Prevent this from happening by bumping dev->power.timer_expires up to 1 if it's 0 before calling mod_timer(). Signed-off-by: Rafael J. Wysocki Reported-by: Alan Stern --- drivers/base/power/runtime.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 6e8577d1f750..637706951885 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -625,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: -- cgit v1.2.3-59-g8ed1b From 965c4ac0613b071d6f035334c5d9d942013df4f9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 3 Dec 2009 21:04:41 +0100 Subject: PM / Runtime: Remove unnecessary braces in __pm_runtime_set_status() Some braces in __pm_runtime_set_status() are not necessary, so remove them. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/runtime.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 637706951885..5a01ecef4af3 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -791,12 +791,10 @@ 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(&parent->power.lock); -- cgit v1.2.3-59-g8ed1b