USB: improve uses of usb_mark_last_busy
authorAlan Stern <stern@rowland.harvard.edu>
Mon, 15 Nov 2010 20:57:58 +0000 (15:57 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 16 Nov 2010 22:04:22 +0000 (14:04 -0800)
This patch (as1434) cleans up the uses of usb_mark_last_busy() in
usbcore.  The function will be called when a device is resumed and
whenever a usage count is decremented.  A call that was missing from
the hub driver is added: A hub is used whenever one of its ports gets
suspended (this prevents hubs from suspending immediately after their
last child).

In addition, the call to disable autosuspend support for new devices
by default is moved from usb_detect_quirks() (where it doesn't really
belong) into usb_new_device() along with all the other runtime-PM
initializations.  Finally, an extra pm_runtime_get_noresume() is added
to prevent new devices from autosuspending while they are being
registered.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/core/driver.c
drivers/usb/core/hub.c
drivers/usb/core/quirks.c

index 43c25c29ac1f54cb3866e7d2f0531927f53bc788..b9278a1fb9e57d9f77a99dcfc4b6b1cb04d01821 100644 (file)
@@ -1261,6 +1261,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg)
                                        udev->reset_resume);
                }
        }
+       usb_mark_last_busy(udev);
 
  done:
        dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status);
@@ -1328,7 +1329,6 @@ int usb_resume(struct device *dev, pm_message_t msg)
                        pm_runtime_disable(dev);
                        pm_runtime_set_active(dev);
                        pm_runtime_enable(dev);
-                       usb_mark_last_busy(udev);
                        do_unbind_rebind(udev, DO_REBIND);
                }
        }
@@ -1660,11 +1660,6 @@ static int usb_runtime_suspend(struct device *dev)
                return -EAGAIN;
 
        status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
-
-       /* Prevent the parent from suspending immediately after */
-       if (status == 0 && udev->parent)
-               usb_mark_last_busy(udev->parent);
-
        return status;
 }
 
@@ -1677,7 +1672,6 @@ static int usb_runtime_resume(struct device *dev)
         * and all its interfaces.
         */
        status = usb_resume_both(udev, PMSG_AUTO_RESUME);
-       usb_mark_last_busy(udev);
        return status;
 }
 
index fdb62ca10d86cb5c9e9ea6059152c0eafca59023..b98efae6a1cfdaaa08b786b45da8c92b56d7f73c 100644 (file)
@@ -1803,9 +1803,15 @@ int usb_new_device(struct usb_device *udev)
 
        /* Tell the runtime-PM framework the device is active */
        pm_runtime_set_active(&udev->dev);
+       pm_runtime_get_noresume(&udev->dev);
        pm_runtime_use_autosuspend(&udev->dev);
        pm_runtime_enable(&udev->dev);
 
+       /* By default, forbid autosuspend for all devices.  It will be
+        * allowed for hubs during binding.
+        */
+       usb_disable_autosuspend(udev);
+
        err = usb_enumerate_device(udev);       /* Read descriptors */
        if (err < 0)
                goto fail;
@@ -1831,6 +1837,8 @@ int usb_new_device(struct usb_device *udev)
        }
 
        (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);
+       usb_mark_last_busy(udev);
+       pm_runtime_put_sync_autosuspend(&udev->dev);
        return err;
 
 fail:
@@ -2221,6 +2229,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
                usb_set_device_state(udev, USB_STATE_SUSPENDED);
                msleep(10);
        }
+       usb_mark_last_busy(hub->hdev);
        return status;
 }
 
index e3531da161374465de25f9eadf58ab138eaca8ef..44c595432d6fec7eff59fadccd0da497244bb17e 100644 (file)
@@ -117,15 +117,6 @@ void usb_detect_quirks(struct usb_device *udev)
                dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
                                udev->quirks);
 
-#ifdef CONFIG_USB_SUSPEND
-
-       /* By default, disable autosuspend for all devices.  The hub driver
-        * will enable it for hubs.
-        */
-       usb_disable_autosuspend(udev);
-
-#endif
-
        /* For the present, all devices default to USB-PERSIST enabled */
 #if 0          /* was: #ifdef CONFIG_PM */
        /* Hubs are automatically enabled for USB-PERSIST */