aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2010-11-15 15:57:58 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-11-16 17:04:22 -0500
commitc08512c761e7b9eaaab0e9167a389393f268e93c (patch)
tree6837bfb8e93915dae46a63a863275f90428f82f0 /drivers/usb/core
parentfcc4a01eb8661226e80632327673f67bf6a5840b (diff)
USB: improve uses of usb_mark_last_busy
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>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/driver.c8
-rw-r--r--drivers/usb/core/hub.c9
-rw-r--r--drivers/usb/core/quirks.c9
3 files changed, 10 insertions, 16 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 43c25c29ac1f..b9278a1fb9e5 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1261,6 +1261,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg)
1261 udev->reset_resume); 1261 udev->reset_resume);
1262 } 1262 }
1263 } 1263 }
1264 usb_mark_last_busy(udev);
1264 1265
1265 done: 1266 done:
1266 dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); 1267 dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status);
@@ -1328,7 +1329,6 @@ int usb_resume(struct device *dev, pm_message_t msg)
1328 pm_runtime_disable(dev); 1329 pm_runtime_disable(dev);
1329 pm_runtime_set_active(dev); 1330 pm_runtime_set_active(dev);
1330 pm_runtime_enable(dev); 1331 pm_runtime_enable(dev);
1331 usb_mark_last_busy(udev);
1332 do_unbind_rebind(udev, DO_REBIND); 1332 do_unbind_rebind(udev, DO_REBIND);
1333 } 1333 }
1334 } 1334 }
@@ -1660,11 +1660,6 @@ static int usb_runtime_suspend(struct device *dev)
1660 return -EAGAIN; 1660 return -EAGAIN;
1661 1661
1662 status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); 1662 status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
1663
1664 /* Prevent the parent from suspending immediately after */
1665 if (status == 0 && udev->parent)
1666 usb_mark_last_busy(udev->parent);
1667
1668 return status; 1663 return status;
1669} 1664}
1670 1665
@@ -1677,7 +1672,6 @@ static int usb_runtime_resume(struct device *dev)
1677 * and all its interfaces. 1672 * and all its interfaces.
1678 */ 1673 */
1679 status = usb_resume_both(udev, PMSG_AUTO_RESUME); 1674 status = usb_resume_both(udev, PMSG_AUTO_RESUME);
1680 usb_mark_last_busy(udev);
1681 return status; 1675 return status;
1682} 1676}
1683 1677
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index fdb62ca10d86..b98efae6a1cf 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1803,9 +1803,15 @@ int usb_new_device(struct usb_device *udev)
1803 1803
1804 /* Tell the runtime-PM framework the device is active */ 1804 /* Tell the runtime-PM framework the device is active */
1805 pm_runtime_set_active(&udev->dev); 1805 pm_runtime_set_active(&udev->dev);
1806 pm_runtime_get_noresume(&udev->dev);
1806 pm_runtime_use_autosuspend(&udev->dev); 1807 pm_runtime_use_autosuspend(&udev->dev);
1807 pm_runtime_enable(&udev->dev); 1808 pm_runtime_enable(&udev->dev);
1808 1809
1810 /* By default, forbid autosuspend for all devices. It will be
1811 * allowed for hubs during binding.
1812 */
1813 usb_disable_autosuspend(udev);
1814
1809 err = usb_enumerate_device(udev); /* Read descriptors */ 1815 err = usb_enumerate_device(udev); /* Read descriptors */
1810 if (err < 0) 1816 if (err < 0)
1811 goto fail; 1817 goto fail;
@@ -1831,6 +1837,8 @@ int usb_new_device(struct usb_device *udev)
1831 } 1837 }
1832 1838
1833 (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); 1839 (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev);
1840 usb_mark_last_busy(udev);
1841 pm_runtime_put_sync_autosuspend(&udev->dev);
1834 return err; 1842 return err;
1835 1843
1836fail: 1844fail:
@@ -2221,6 +2229,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
2221 usb_set_device_state(udev, USB_STATE_SUSPENDED); 2229 usb_set_device_state(udev, USB_STATE_SUSPENDED);
2222 msleep(10); 2230 msleep(10);
2223 } 2231 }
2232 usb_mark_last_busy(hub->hdev);
2224 return status; 2233 return status;
2225} 2234}
2226 2235
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index e3531da16137..44c595432d6f 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -117,15 +117,6 @@ void usb_detect_quirks(struct usb_device *udev)
117 dev_dbg(&udev->dev, "USB quirks for this device: %x\n", 117 dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
118 udev->quirks); 118 udev->quirks);
119 119
120#ifdef CONFIG_USB_SUSPEND
121
122 /* By default, disable autosuspend for all devices. The hub driver
123 * will enable it for hubs.
124 */
125 usb_disable_autosuspend(udev);
126
127#endif
128
129 /* For the present, all devices default to USB-PERSIST enabled */ 120 /* For the present, all devices default to USB-PERSIST enabled */
130#if 0 /* was: #ifdef CONFIG_PM */ 121#if 0 /* was: #ifdef CONFIG_PM */
131 /* Hubs are automatically enabled for USB-PERSIST */ 122 /* Hubs are automatically enabled for USB-PERSIST */