From 5899f1e020c8d53b2b6fbd6a6cf39c891ccdfade Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 8 Jan 2010 12:57:02 -0500 Subject: 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 Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/sysfs.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers/usb/core/sysfs.c') diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 313e241..43c002e 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, const char *buf, size_t count) { struct usb_device *udev = to_usb_device(dev); - int value; + int value, old_delay; + int rc; if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ || value <= - INT_MAX/HZ) @@ -354,13 +355,24 @@ set_autosuspend(struct device *dev, struct device_attribute *attr, value *= HZ; usb_lock_device(udev); + old_delay = udev->autosuspend_delay; udev->autosuspend_delay = value; - if (value >= 0) - usb_try_autosuspend_device(udev); - else { - if (usb_autoresume_device(udev) == 0) + + if (old_delay < 0) { /* Autosuspend wasn't allowed */ + if (value >= 0) usb_autosuspend_device(udev); + } else { /* Autosuspend was allowed */ + if (value < 0) { + rc = usb_autoresume_device(udev); + if (rc < 0) { + count = rc; + udev->autosuspend_delay = old_delay; + } + } else { + usb_try_autosuspend_device(udev); + } } + usb_unlock_device(udev); return count; } -- cgit v1.1