PM / Runtime: Don't allow to suspend a device with an active child
authorUlf Hansson <ulf.hansson@linaro.org>
Mon, 17 Oct 2016 18:17:01 +0000 (20:17 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 9 Nov 2016 14:49:37 +0000 (15:49 +0100)
When resuming a device in __pm_runtime_set_status(), the prerequisite is
that its parent must already be active, else an error code is returned and
the device's status remains suspended.

When suspending a device there is no similar constraints being validated.
Let's change this to make the behaviour consistent, by not allowing to
suspend a device with an active child, unless it has been explicitly set to
ignore its children.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/base/power/runtime.c

index 117db71e84cb11e38800c2f959dc9ed6188b054c..60ebb04d8140cba80d2efccee6df5937ffd230ab 100644 (file)
@@ -1028,7 +1028,17 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
                goto out_set;
 
        if (status == RPM_SUSPENDED) {
-               /* It always is possible to set the status to 'suspended'. */
+               /*
+                * It is invalid to suspend a device with an active child,
+                * unless it has been set to ignore its children.
+                */
+               if (!dev->power.ignore_children &&
+                       atomic_read(&dev->power.child_count)) {
+                       dev_err(dev, "runtime PM trying to suspend device but active child\n");
+                       error = -EBUSY;
+                       goto out;
+               }
+
                if (parent) {
                        atomic_add_unless(&parent->power.child_count, -1, 0);
                        notify_parent = !parent->power.ignore_children;