aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/core/driver.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-03-20 14:59:39 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-04-27 13:28:37 -0700
commit2add5229d77a3de08015feef437653e02372162f (patch)
tree436109572453656747d6e5b3aec14939b1202ec3 /drivers/usb/core/driver.c
parent13f6be01db9ada144f28241f939f4f3f8ec8e40b (diff)
USB: add power/level sysfs attribute
This patch (as874) adds another piece to the user-visible part of the USB autosuspend interface. The new power/level sysfs attribute allows users to force the device on (with autosuspend off), force the device to sleep (with autoresume off), or return to normal automatic operation. 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.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 884179f1e16..9b6a60fafdd 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -872,8 +872,10 @@ static int usb_resume_device(struct usb_device *udev)
done:
// dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
- if (status == 0)
+ if (status == 0) {
+ udev->autoresume_disabled = 0;
udev->dev.power.power_state.event = PM_EVENT_ON;
+ }
return status;
}
@@ -970,7 +972,7 @@ static int autosuspend_check(struct usb_device *udev)
udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
if (udev->pm_usage_cnt > 0)
return -EBUSY;
- if (udev->autosuspend_delay < 0)
+ if (udev->autosuspend_delay < 0 || udev->autosuspend_disabled)
return -EPERM;
if (udev->actconfig) {
@@ -1116,6 +1118,8 @@ static int usb_resume_both(struct usb_device *udev)
struct usb_interface *intf;
struct usb_device *parent = udev->parent;
+ if (udev->auto_pm && udev->autoresume_disabled)
+ return -EPERM;
cancel_delayed_work(&udev->autosuspend);
if (udev->state == USB_STATE_NOTATTACHED)
return -ENODEV;
@@ -1486,9 +1490,14 @@ static int usb_suspend(struct device *dev, pm_message_t message)
static int usb_resume(struct device *dev)
{
+ struct usb_device *udev;
+
if (!is_usb_device(dev)) /* Ignore PM for interfaces */
return 0;
- return usb_external_resume_device(to_usb_device(dev));
+ udev = to_usb_device(dev);
+ if (udev->autoresume_disabled)
+ return -EPERM;
+ return usb_external_resume_device(udev);
}
#else