aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2010-01-08 12:57:02 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 17:54:11 -0500
commit5899f1e020c8d53b2b6fbd6a6cf39c891ccdfade (patch)
treeacd9041996aa81db4bdc9a30fe1926e511d7eb77 /drivers/usb/core
parent088f7fec8a0e683db72fd8826c5d3ab914e197b1 (diff)
USB: change handling of negative autosuspend delays
This patch (as1327) changes the way negative autosuspend delays prevent device from autosuspending. The current code checks for negative values explicitly in the autosuspend_check() routine. The updated code keeps things from getting that far by using usb_autoresume_device() to increment the usage counter when a negative delay is set, and by using usb_autosuspend_device() to decrement the usage counter when a non-negative delay is set. This complicates the set_autosuspend() attribute method code slightly, but it will reduce the overall power management overhead. 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/quirks.c10
-rw-r--r--drivers/usb/core/sysfs.c22
2 files changed, 27 insertions, 5 deletions
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 4314f259524..f073c5cb4e7 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -103,11 +103,21 @@ void usb_detect_quirks(struct usb_device *udev)
103 dev_dbg(&udev->dev, "USB quirks for this device: %x\n", 103 dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
104 udev->quirks); 104 udev->quirks);
105 105
106#ifdef CONFIG_USB_SUSPEND
107
106 /* By default, disable autosuspend for all devices. The hub driver 108 /* By default, disable autosuspend for all devices. The hub driver
107 * will enable it for hubs. 109 * will enable it for hubs.
108 */ 110 */
109 usb_disable_autosuspend(udev); 111 usb_disable_autosuspend(udev);
110 112
113 /* Autosuspend can also be disabled if the initial autosuspend_delay
114 * is negative.
115 */
116 if (udev->autosuspend_delay < 0)
117 usb_autoresume_device(udev);
118
119#endif
120
111 /* For the present, all devices default to USB-PERSIST enabled */ 121 /* For the present, all devices default to USB-PERSIST enabled */
112#if 0 /* was: #ifdef CONFIG_PM */ 122#if 0 /* was: #ifdef CONFIG_PM */
113 /* Hubs are automatically enabled for USB-PERSIST */ 123 /* Hubs are automatically enabled for USB-PERSIST */
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 313e241f5cc..43c002e3a9a 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -346,7 +346,8 @@ set_autosuspend(struct device *dev, struct device_attribute *attr,
346 const char *buf, size_t count) 346 const char *buf, size_t count)
347{ 347{
348 struct usb_device *udev = to_usb_device(dev); 348 struct usb_device *udev = to_usb_device(dev);
349 int value; 349 int value, old_delay;
350 int rc;
350 351
351 if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ || 352 if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ ||
352 value <= - INT_MAX/HZ) 353 value <= - INT_MAX/HZ)
@@ -354,13 +355,24 @@ set_autosuspend(struct device *dev, struct device_attribute *attr,
354 value *= HZ; 355 value *= HZ;
355 356
356 usb_lock_device(udev); 357 usb_lock_device(udev);
358 old_delay = udev->autosuspend_delay;
357 udev->autosuspend_delay = value; 359 udev->autosuspend_delay = value;
358 if (value >= 0) 360
359 usb_try_autosuspend_device(udev); 361 if (old_delay < 0) { /* Autosuspend wasn't allowed */
360 else { 362 if (value >= 0)
361 if (usb_autoresume_device(udev) == 0)
362 usb_autosuspend_device(udev); 363 usb_autosuspend_device(udev);
364 } else { /* Autosuspend was allowed */
365 if (value < 0) {
366 rc = usb_autoresume_device(udev);
367 if (rc < 0) {
368 count = rc;
369 udev->autosuspend_delay = old_delay;
370 }
371 } else {
372 usb_try_autosuspend_device(udev);
373 }
363 } 374 }
375
364 usb_unlock_device(udev); 376 usb_unlock_device(udev);
365 return count; 377 return count;
366} 378}