usb: core: Temporary workaround for usb auto-suspend issue
authorBenoit Goby <benoit@android.com>
Mon, 22 Nov 2010 22:46:05 +0000 (14:46 -0800)
committerBenoit Goby <benoit@android.com>
Tue, 23 Nov 2010 01:51:08 +0000 (17:51 -0800)
If a device aborts suspend, usb_resume may be called on a device whose
parent has been auto-suspended. Recursively resume its parents and
change their runtime pm state.

Change-Id: I8f96482bdafae3888a0df9cb30422236a001e17d
Signed-off-by: Benoit Goby <benoit@android.com>
drivers/usb/core/driver.c

index d7a4401ef0192e2a0d4870a5d27bee082b35890a..ffa3e22083c26af68ddb695dd85230416d76e783 100644 (file)
@@ -1324,6 +1324,20 @@ int usb_resume(struct device *dev, pm_message_t msg)
         * Unbind the interfaces that will need rebinding later.
         */
        } else {
+               /* If a device aborts suspend, usb_resume may be called on a
+                * device whose parent has been auto-suspended. Recursively
+                * resume its parents and change their runtime pm state.
+                */
+               if (udev->parent && msg.event == PM_EVENT_RESUME
+                           && udev->parent->state == USB_STATE_SUSPENDED) {
+                       status = usb_resume(&udev->parent->dev, msg);
+                       if (status) {
+                               dev_err(dev, "%s: failed to resume parent\n",
+                                               __func__);
+                               return status;
+                       }
+               }
+
                status = usb_resume_both(udev, msg);
                if (status == 0) {
                        pm_runtime_disable(dev);