aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2013-03-27 16:14:19 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-28 14:06:27 -0400
commit0aa2832dd0d9d8609fd8f15139bc7572541a1215 (patch)
tree9537cc80217eca1614ca988a87b34170b8dbcc8f
parente9e88fb7bca9f527ccdf4166a240a9023ba6ee73 (diff)
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>
-rw-r--r--drivers/usb/core/hub.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 669da9ef714d..443d5cc9330b 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2886,9 +2886,11 @@ static int usb_disable_function_remotewakeup(struct usb_device *udev)
2886 * Linux (2.6) currently has NO mechanisms to initiate that: no khubd 2886 * Linux (2.6) currently has NO mechanisms to initiate that: no khubd
2887 * timer, no SRP, no requests through sysfs. 2887 * timer, no SRP, no requests through sysfs.
2888 * 2888 *
2889 * If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when 2889 * If CONFIG_USB_SUSPEND isn't enabled, non-SuperSpeed devices really get
2890 * the root hub for their bus goes into global suspend ... so we don't 2890 * suspended only when their bus goes into global suspend (i.e., the root
2891 * (falsely) update the device power state to say it suspended. 2891 * hub is suspended). Nevertheless, we change @udev->state to
2892 * USB_STATE_SUSPENDED as this is the device's "logical" state. The actual
2893 * upstream port setting is stored in @udev->port_is_suspended.
2892 * 2894 *
2893 * Returns 0 on success, else negative errno. 2895 * Returns 0 on success, else negative errno.
2894 */ 2896 */
@@ -2899,6 +2901,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
2899 enum pm_qos_flags_status pm_qos_stat; 2901 enum pm_qos_flags_status pm_qos_stat;
2900 int port1 = udev->portnum; 2902 int port1 = udev->portnum;
2901 int status; 2903 int status;
2904 bool really_suspend = true;
2902 2905
2903 /* enable remote wakeup when appropriate; this lets the device 2906 /* enable remote wakeup when appropriate; this lets the device
2904 * wake up the upstream hub (including maybe the root hub). 2907 * 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 /* see 7.1.7.6 */ 2958 /* see 7.1.7.6 */
2956 if (hub_is_superspeed(hub->hdev)) 2959 if (hub_is_superspeed(hub->hdev))
2957 status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3); 2960 status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3);
2958 else 2961 else if (PMSG_IS_AUTO(msg))
2959 status = set_port_feature(hub->hdev, port1, 2962 status = set_port_feature(hub->hdev, port1,
2960 USB_PORT_FEAT_SUSPEND); 2963 USB_PORT_FEAT_SUSPEND);
2964 /*
2965 * For system suspend, we do not need to enable the suspend feature
2966 * on individual USB-2 ports. The devices will automatically go
2967 * into suspend a few ms after the root hub stops sending packets.
2968 * The USB 2.0 spec calls this "global suspend".
2969 */
2970 else {
2971 really_suspend = false;
2972 status = 0;
2973 }
2961 if (status) { 2974 if (status) {
2962 dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", 2975 dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
2963 port1, status); 2976 port1, status);
@@ -2993,8 +3006,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
2993 (PMSG_IS_AUTO(msg) ? "auto-" : ""), 3006 (PMSG_IS_AUTO(msg) ? "auto-" : ""),
2994 udev->do_remote_wakeup); 3007 udev->do_remote_wakeup);
2995 usb_set_device_state(udev, USB_STATE_SUSPENDED); 3008 usb_set_device_state(udev, USB_STATE_SUSPENDED);
2996 udev->port_is_suspended = 1; 3009 if (really_suspend) {
2997 msleep(10); 3010 udev->port_is_suspended = 1;
3011 msleep(10);
3012 }
2998 } 3013 }
2999 3014
3000 /* 3015 /*