Commit 0aa2832d authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

USB: use "global suspend" for system sleep on USB-2 buses

This patch (as1674) speeds up system sleep transitions by not
suspending each individual device on a USB-1.1 or USB-2 bus.  The
devices will automatically go into suspend when their root hubs are
suspended (i.e., stop sending out Start-Of-Frame packets) -- this is
what the USB spec calls "global suspend".

Since this is what we do already when CONFIG_USB_SUSPEND isn't
enabled, it shouldn't cause any problems.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
CC: Peter Chen <peter.chen@freescale.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e9e88fb7
...@@ -2886,9 +2886,11 @@ static int usb_disable_function_remotewakeup(struct usb_device *udev) ...@@ -2886,9 +2886,11 @@ static int usb_disable_function_remotewakeup(struct usb_device *udev)
* Linux (2.6) currently has NO mechanisms to initiate that: no khubd * Linux (2.6) currently has NO mechanisms to initiate that: no khubd
* timer, no SRP, no requests through sysfs. * timer, no SRP, no requests through sysfs.
* *
* If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when * If CONFIG_USB_SUSPEND isn't enabled, non-SuperSpeed devices really get
* the root hub for their bus goes into global suspend ... so we don't * suspended only when their bus goes into global suspend (i.e., the root
* (falsely) update the device power state to say it suspended. * hub is suspended). Nevertheless, we change @udev->state to
* USB_STATE_SUSPENDED as this is the device's "logical" state. The actual
* upstream port setting is stored in @udev->port_is_suspended.
* *
* Returns 0 on success, else negative errno. * Returns 0 on success, else negative errno.
*/ */
...@@ -2899,6 +2901,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) ...@@ -2899,6 +2901,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
enum pm_qos_flags_status pm_qos_stat; enum pm_qos_flags_status pm_qos_stat;
int port1 = udev->portnum; int port1 = udev->portnum;
int status; int status;
bool really_suspend = true;
/* enable remote wakeup when appropriate; this lets the device /* enable remote wakeup when appropriate; this lets the device
* wake up the upstream hub (including maybe the root hub). * wake up the upstream hub (including maybe the root hub).
...@@ -2955,9 +2958,19 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) ...@@ -2955,9 +2958,19 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
/* see 7.1.7.6 */ /* see 7.1.7.6 */
if (hub_is_superspeed(hub->hdev)) if (hub_is_superspeed(hub->hdev))
status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3); status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3);
else else if (PMSG_IS_AUTO(msg))
status = set_port_feature(hub->hdev, port1, status = set_port_feature(hub->hdev, port1,
USB_PORT_FEAT_SUSPEND); USB_PORT_FEAT_SUSPEND);
/*
* For system suspend, we do not need to enable the suspend feature
* on individual USB-2 ports. The devices will automatically go
* into suspend a few ms after the root hub stops sending packets.
* The USB 2.0 spec calls this "global suspend".
*/
else {
really_suspend = false;
status = 0;
}
if (status) { if (status) {
dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
port1, status); port1, status);
...@@ -2993,8 +3006,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) ...@@ -2993,8 +3006,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
(PMSG_IS_AUTO(msg) ? "auto-" : ""), (PMSG_IS_AUTO(msg) ? "auto-" : ""),
udev->do_remote_wakeup); udev->do_remote_wakeup);
usb_set_device_state(udev, USB_STATE_SUSPENDED); usb_set_device_state(udev, USB_STATE_SUSPENDED);
udev->port_is_suspended = 1; if (really_suspend) {
msleep(10); udev->port_is_suspended = 1;
msleep(10);
}
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment