diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2010-04-02 13:18:50 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-20 16:21:37 -0400 |
commit | 7560d32ec70508a71f537a88e40f7717f15389ac (patch) | |
tree | 26ad39a57917f74ede0aafe7dd6d7e48fb707694 /drivers | |
parent | ff9c895f07d36193c75533bda8193bde8ca99d02 (diff) |
USB: improve runtime remote wakeup settings
This patch (as1362) adjusts the way the USB autosuspend routines
handle remote-wakeup settings. They aren't supposed to use
device_may_wakeup(); that test is intended only for system sleep, not
runtime power management. Instead the code checks to see if any
interface drivers need remote wakeup; if they do then it is enabled,
provided the device is capable of it.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/driver.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index edff55a32575..271e857be0fa 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -1486,9 +1486,6 @@ int usb_autoresume_device(struct usb_device *udev) | |||
1486 | * 0, a delayed autosuspend request for @intf's device is attempted. The | 1486 | * 0, a delayed autosuspend request for @intf's device is attempted. The |
1487 | * attempt may fail (see autosuspend_check()). | 1487 | * attempt may fail (see autosuspend_check()). |
1488 | * | 1488 | * |
1489 | * If the driver has set @intf->needs_remote_wakeup then autosuspend will | ||
1490 | * take place only if the device's remote-wakeup facility is enabled. | ||
1491 | * | ||
1492 | * This routine can run only in process context. | 1489 | * This routine can run only in process context. |
1493 | */ | 1490 | */ |
1494 | void usb_autopm_put_interface(struct usb_interface *intf) | 1491 | void usb_autopm_put_interface(struct usb_interface *intf) |
@@ -1673,14 +1670,14 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interface_no_resume); | |||
1673 | /* Internal routine to check whether we may autosuspend a device. */ | 1670 | /* Internal routine to check whether we may autosuspend a device. */ |
1674 | static int autosuspend_check(struct usb_device *udev) | 1671 | static int autosuspend_check(struct usb_device *udev) |
1675 | { | 1672 | { |
1676 | int i; | 1673 | int w, i; |
1677 | struct usb_interface *intf; | 1674 | struct usb_interface *intf; |
1678 | unsigned long suspend_time, j; | 1675 | unsigned long suspend_time, j; |
1679 | 1676 | ||
1680 | /* Fail if autosuspend is disabled, or any interfaces are in use, or | 1677 | /* Fail if autosuspend is disabled, or any interfaces are in use, or |
1681 | * any interface drivers require remote wakeup but it isn't available. | 1678 | * any interface drivers require remote wakeup but it isn't available. |
1682 | */ | 1679 | */ |
1683 | udev->do_remote_wakeup = device_may_wakeup(&udev->dev); | 1680 | w = 0; |
1684 | if (udev->actconfig) { | 1681 | if (udev->actconfig) { |
1685 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | 1682 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
1686 | intf = udev->actconfig->interface[i]; | 1683 | intf = udev->actconfig->interface[i]; |
@@ -1694,12 +1691,7 @@ static int autosuspend_check(struct usb_device *udev) | |||
1694 | continue; | 1691 | continue; |
1695 | if (atomic_read(&intf->dev.power.usage_count) > 0) | 1692 | if (atomic_read(&intf->dev.power.usage_count) > 0) |
1696 | return -EBUSY; | 1693 | return -EBUSY; |
1697 | if (intf->needs_remote_wakeup && | 1694 | w |= intf->needs_remote_wakeup; |
1698 | !udev->do_remote_wakeup) { | ||
1699 | dev_dbg(&udev->dev, "remote wakeup needed " | ||
1700 | "for autosuspend\n"); | ||
1701 | return -EOPNOTSUPP; | ||
1702 | } | ||
1703 | 1695 | ||
1704 | /* Don't allow autosuspend if the device will need | 1696 | /* Don't allow autosuspend if the device will need |
1705 | * a reset-resume and any of its interface drivers | 1697 | * a reset-resume and any of its interface drivers |
@@ -1715,6 +1707,11 @@ static int autosuspend_check(struct usb_device *udev) | |||
1715 | } | 1707 | } |
1716 | } | 1708 | } |
1717 | } | 1709 | } |
1710 | if (w && !device_can_wakeup(&udev->dev)) { | ||
1711 | dev_dbg(&udev->dev, "remote wakeup needed for autosuspend\n"); | ||
1712 | return -EOPNOTSUPP; | ||
1713 | } | ||
1714 | udev->do_remote_wakeup = w; | ||
1718 | 1715 | ||
1719 | /* If everything is okay but the device hasn't been idle for long | 1716 | /* If everything is okay but the device hasn't been idle for long |
1720 | * enough, queue a delayed autosuspend request. | 1717 | * enough, queue a delayed autosuspend request. |