From 9f5b52747dbf83816dcd29ea1700813aeb668c0f Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 30 May 2016 11:33:12 +0200 Subject: PM / Runtime: Avoid resuming devices again in pm_runtime_force_resume() If the runtime PM status of the device isn't RPM_SUSPENDED, prevent the pm_runtime_force_resume() from invoking the ->runtime_resume() callback for the device, as it's not the expected behaviour from the subsystem/driver. Signed-off-by: Ulf Hansson Reviewed-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- drivers/base/power/runtime.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/base/power/runtime.c') diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index b74690418504..09e4eb1a7286 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1506,6 +1506,9 @@ int pm_runtime_force_resume(struct device *dev) goto out; } + if (!pm_runtime_status_suspended(dev)) + goto out; + ret = pm_runtime_set_active(dev); if (ret) goto out; -- cgit v1.2.3 From 71723f95463d284004bd0afe1825e6790a0c90d0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 20 Jun 2016 11:14:26 +0200 Subject: PM / runtime: print error when activating a child to unactive parent The code currently silently bails out with -EBUSY if you try to activate a child to an inactive parent. This typically happens when you have a runtime suspended parent and runtime resume your child, but forgot to set .ignore_children on the parent to true with pm_suspend_ignore_children(dev). Silently ignoring this error is not good as it gives rise to other strange behaviour like double-resume of devices after silently bailing out of the .runtime_resume() callback. Signed-off-by: Linus Walleij Signed-off-by: Rafael J. Wysocki --- drivers/base/power/runtime.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/base/power/runtime.c') diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index b74690418504..e7ee8293055b 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1045,10 +1045,14 @@ 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) { + dev_err(dev, "runtime PM trying to activate child device %s but parent (%s) is not active\n", + dev_name(dev), + dev_name(parent)); error = -EBUSY; - else if (dev->power.runtime_status == RPM_SUSPENDED) + } else if (dev->power.runtime_status == RPM_SUSPENDED) { atomic_inc(&parent->power.child_count); + } spin_unlock(&parent->power.lock); -- cgit v1.2.3 From fe7450b05fddebd5a76a5ad280a5ae9a82ce336f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 29 Jun 2016 02:53:48 +0200 Subject: PM / runtime: Asynchronous "idle" in pm_runtime_allow() Arjan reports that it takes a relatively long time to enable runtime PM for multiple devices at system startup, because all writes to the "control" attribute in sysfs are handled synchronously and if the device is suspended as a result of the write, it will block until that operation is complete. That may be avoided by passing the RPM_ASYNC flag to rpm_idle() in pm_runtime_allow() which will make it execute the device's "idle" callback asynchronously, so writes to "control" changing it from "on" to "auto" will return without waiting. Reported-by: Arjan van de Ven Signed-off-by: Rafael J. Wysocki Acked-by: Alan Stern Reviewed-by: Ulf Hansson Reviewed-by: Kevin Hilman --- drivers/base/power/runtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/base/power/runtime.c') diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index e7ee8293055b..aa3ea5e25377 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1260,7 +1260,7 @@ void pm_runtime_allow(struct device *dev) dev->power.runtime_auto = true; if (atomic_dec_and_test(&dev->power.usage_count)) - rpm_idle(dev, RPM_AUTO); + rpm_idle(dev, RPM_AUTO | RPM_ASYNC); out: spin_unlock_irq(&dev->power.lock); -- cgit v1.2.3