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: Alan Stern <stern@rowland.harvard.edu> CC: Peter Chen <peter.chen@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
e9e88fb7bc
commit
0aa2832dd0
@ -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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
(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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user