USB: Allow autosuspend delay to equal 0

This patch (as867) adds an entry for the new power/autosuspend
attribute in Documentation/ABI/testing, and it changes the behavior of
the delay value.  Now a delay of 0 means to autosuspend as soon as
possible, and negative values will prevent autosuspend.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Alan Stern 2007-03-13 16:39:15 -04:00 committed by Greg Kroah-Hartman
parent 6b157c9bf3
commit eaafbc3a8a
6 changed files with 29 additions and 10 deletions

View File

@ -0,0 +1,15 @@
What: /sys/bus/usb/devices/.../power/autosuspend
Date: March 2007
KernelVersion: 2.6.21
Contact: Alan Stern <stern@rowland.harvard.edu>
Description:
Each USB device directory will contain a file named
power/autosuspend. This file holds the time (in seconds)
the device must be idle before it will be autosuspended.
0 means the device will be autosuspended as soon as
possible. Negative values will prevent the device from
being autosuspended at all, and writing a negative value
will resume the device if it is already suspended.
The autosuspend delay for newly-created devices is set to
the value of the usbcore.autosuspend module parameter.

View File

@ -1792,7 +1792,7 @@ and is between 256 and 4096 characters. It is defined in the file
for newly-detected USB devices (default 2). This for newly-detected USB devices (default 2). This
is the time required before an idle device will be is the time required before an idle device will be
autosuspended. Devices for which the delay is set autosuspended. Devices for which the delay is set
to 0 won't be autosuspended at all. to a negative value won't be autosuspended at all.
usbhid.mousepoll= usbhid.mousepoll=
[USBHID] The interval which mice are to be polled at. [USBHID] The interval which mice are to be polled at.

View File

@ -970,7 +970,7 @@ static int autosuspend_check(struct usb_device *udev)
udev->do_remote_wakeup = device_may_wakeup(&udev->dev); udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
if (udev->pm_usage_cnt > 0) if (udev->pm_usage_cnt > 0)
return -EBUSY; return -EBUSY;
if (!udev->autosuspend_delay) if (udev->autosuspend_delay < 0)
return -EPERM; return -EPERM;
if (udev->actconfig) { if (udev->actconfig) {

View File

@ -165,7 +165,7 @@ show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf)
{ {
struct usb_device *udev = to_usb_device(dev); struct usb_device *udev = to_usb_device(dev);
return sprintf(buf, "%u\n", udev->autosuspend_delay / HZ); return sprintf(buf, "%d\n", udev->autosuspend_delay / HZ);
} }
static ssize_t static ssize_t
@ -173,17 +173,21 @@ set_autosuspend(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct usb_device *udev = to_usb_device(dev); struct usb_device *udev = to_usb_device(dev);
unsigned value, old; int value;
if (sscanf(buf, "%u", &value) != 1 || value >= INT_MAX/HZ) if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ ||
value <= - INT_MAX/HZ)
return -EINVAL; return -EINVAL;
value *= HZ; value *= HZ;
old = udev->autosuspend_delay;
udev->autosuspend_delay = value; udev->autosuspend_delay = value;
if (value > 0 && old == 0) if (value >= 0)
usb_try_autosuspend_device(udev); usb_try_autosuspend_device(udev);
else {
usb_lock_device(udev);
usb_external_resume_device(udev);
usb_unlock_device(udev);
}
return count; return count;
} }

View File

@ -55,7 +55,7 @@ struct workqueue_struct *ksuspend_usb_wq;
#ifdef CONFIG_USB_SUSPEND #ifdef CONFIG_USB_SUSPEND
static int usb_autosuspend_delay = 2; /* Default delay value, static int usb_autosuspend_delay = 2; /* Default delay value,
* in seconds */ * in seconds */
module_param_named(autosuspend, usb_autosuspend_delay, uint, 0644); module_param_named(autosuspend, usb_autosuspend_delay, int, 0644);
MODULE_PARM_DESC(autosuspend, "default autosuspend delay"); MODULE_PARM_DESC(autosuspend, "default autosuspend delay");
#else #else

View File

@ -394,7 +394,7 @@ struct usb_device {
struct delayed_work autosuspend; /* for delayed autosuspends */ struct delayed_work autosuspend; /* for delayed autosuspends */
struct mutex pm_mutex; /* protects PM operations */ struct mutex pm_mutex; /* protects PM operations */
unsigned autosuspend_delay; /* in jiffies */ int autosuspend_delay; /* in jiffies */
unsigned auto_pm:1; /* autosuspend/resume in progress */ unsigned auto_pm:1; /* autosuspend/resume in progress */
unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */ unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */