Skip to content

Commit 7560d32

Browse files
AlanSterngregkh
authored andcommitted
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 <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ff9c895 commit 7560d32

File tree

1 file changed

+8
-11
lines changed

1 file changed

+8
-11
lines changed

drivers/usb/core/driver.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,9 +1486,6 @@ int usb_autoresume_device(struct usb_device *udev)
14861486
* 0, a delayed autosuspend request for @intf's device is attempted. The
14871487
* attempt may fail (see autosuspend_check()).
14881488
*
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-
*
14921489
* This routine can run only in process context.
14931490
*/
14941491
void usb_autopm_put_interface(struct usb_interface *intf)
@@ -1673,14 +1670,14 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interface_no_resume);
16731670
/* Internal routine to check whether we may autosuspend a device. */
16741671
static int autosuspend_check(struct usb_device *udev)
16751672
{
1676-
int i;
1673+
int w, i;
16771674
struct usb_interface *intf;
16781675
unsigned long suspend_time, j;
16791676

16801677
/* Fail if autosuspend is disabled, or any interfaces are in use, or
16811678
* any interface drivers require remote wakeup but it isn't available.
16821679
*/
1683-
udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
1680+
w = 0;
16841681
if (udev->actconfig) {
16851682
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
16861683
intf = udev->actconfig->interface[i];
@@ -1694,12 +1691,7 @@ static int autosuspend_check(struct usb_device *udev)
16941691
continue;
16951692
if (atomic_read(&intf->dev.power.usage_count) > 0)
16961693
return -EBUSY;
1697-
if (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-
}
1694+
w |= intf->needs_remote_wakeup;
17031695

17041696
/* Don't allow autosuspend if the device will need
17051697
* a reset-resume and any of its interface drivers
@@ -1715,6 +1707,11 @@ static int autosuspend_check(struct usb_device *udev)
17151707
}
17161708
}
17171709
}
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;
17181715

17191716
/* If everything is okay but the device hasn't been idle for long
17201717
* enough, queue a delayed autosuspend request.

0 commit comments

Comments
 (0)