diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-03-20 14:59:39 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-04-27 13:28:37 -0700 |
commit | 2add5229d77a3de08015feef437653e02372162f (patch) | |
tree | 436109572453656747d6e5b3aec14939b1202ec3 /drivers/usb/core/driver.c | |
parent | 13f6be01db9ada144f28241f939f4f3f8ec8e40b (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.c | 15 |
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 |