diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2010-01-08 12:56:54 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-02 14:54:10 -0800 |
commit | 088f7fec8a0e683db72fd8826c5d3ab914e197b1 (patch) | |
tree | 971ef100d0db9727e4403865b67c72de62e8247a /drivers/usb/core/driver.c | |
parent | 0c4db6df915bc470f0cd32fe48287fa6eb6adfb4 (diff) |
USB: implement usb_enable_autosuspend
This patch (as1326) adds usb_enable_autosuspend() and
usb_disable_autosuspend() routines for use by drivers. If a driver
knows that its device can handle suspends and resumes correctly, it
can enable autosuspend all by itself. This is equivalent to the user
writing "auto" to the device's power/level attribute.
The implementation differs slightly from what it used to be. Now
autosuspend is disabled simply by doing usb_autoresume_device() (to
increment the usage counter) and enabled by doing
usb_autosuspend_device() (to decrement the usage counter).
The set_level() attribute method is updated to use the new routines,
and the USB Power-Management documentation is updated.
The patch adds a usb_enable_autosuspend() call to the hub driver's
probe routine, allowing the special-case code for hubs in quirks.c to
be removed.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/driver.c')
-rw-r--r-- | drivers/usb/core/driver.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 2b39583040d..057eeab0600 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1415,6 +1415,48 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) #ifdef CONFIG_USB_SUSPEND +/** + * usb_enable_autosuspend - allow a USB device to be autosuspended + * @udev: the USB device which may be autosuspended + * + * This routine allows @udev to be autosuspended. An autosuspend won't + * take place until the autosuspend_delay has elapsed and all the other + * necessary conditions are satisfied. + * + * The caller must hold @udev's device lock. + */ +int usb_enable_autosuspend(struct usb_device *udev) +{ + if (udev->autosuspend_disabled) { + udev->autosuspend_disabled = 0; + usb_autosuspend_device(udev); + } + return 0; +} +EXPORT_SYMBOL_GPL(usb_enable_autosuspend); + +/** + * usb_disable_autosuspend - prevent a USB device from being autosuspended + * @udev: the USB device which may not be autosuspended + * + * This routine prevents @udev from being autosuspended and wakes it up + * if it is already autosuspended. + * + * The caller must hold @udev's device lock. + */ +int usb_disable_autosuspend(struct usb_device *udev) +{ + int rc = 0; + + if (!udev->autosuspend_disabled) { + rc = usb_autoresume_device(udev); + if (rc == 0) + udev->autosuspend_disabled = 1; + } + return rc; +} +EXPORT_SYMBOL_GPL(usb_disable_autosuspend); + /* Internal routine to adjust a device's usage counter and change * its autosuspend state. */ |