aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLan Tianyu <tianyu.lan@intel.com>2013-01-22 15:26:30 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-25 13:14:20 -0500
commitad493e5e580546e6c3024b76a41535476da1546a (patch)
tree256edf0ac3bc23573c0daa0b66a985970c489f61
parent971fcd492cebf544714f12d94549d2f0d2002645 (diff)
usb: add usb port auto power off mechanism
This patch is to add usb port auto power off mechanism. When usb device is suspending, usb core will suspend usb port and usb port runtime pm callback will clear PORT_POWER feature to power off port if all conditions were met. These conditions are remote wakeup disable, pm qos NO_POWER_OFF flag clear and persist enable. When it resumes, power on port again. Add did_runtime_put in the struct usb_port to ensure pm_runtime_get/put(portdev) to be called pairedly. Set did_runtime_put to true when call pm_runtime_put(portdev) during suspending. The pm_runtime_get(portdev) only will be called when did_runtime_put is set to true during resuming. Set did_runtime_put to false after calling pm_runtime_get(portdev). Make clear_port_feature() and hdev_to_hub() as global symbol. Rename clear_port_feature() to usb_clear_port_feature() and hdev_to_hub() to usb_hub_to_struct_hub(). Extend hub_port_debounce() with the fuction of debouncing to be connected. Add two wraps: hub_port_debounce_be_connected() and hub_port_debouce_be_stable(). Increase HUB_DEBOUNCE_TIMEOUT to 2000 because some usb ssds needs around 1.5 or more to make the hub port status to be connected steadily after being powered off and powered on. Acked-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/core/hub.c161
-rw-r--r--drivers/usb/core/hub.h21
-rw-r--r--drivers/usb/core/port.c40
3 files changed, 164 insertions, 58 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 7fb163365d02..0883364e7347 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -26,6 +26,7 @@
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/freezer.h> 27#include <linux/freezer.h>
28#include <linux/random.h> 28#include <linux/random.h>
29#include <linux/pm_qos.h>
29 30
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <asm/byteorder.h> 32#include <asm/byteorder.h>
@@ -108,7 +109,7 @@ MODULE_PARM_DESC(use_both_schemes,
108DECLARE_RWSEM(ehci_cf_port_reset_rwsem); 109DECLARE_RWSEM(ehci_cf_port_reset_rwsem);
109EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); 110EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
110 111
111#define HUB_DEBOUNCE_TIMEOUT 1500 112#define HUB_DEBOUNCE_TIMEOUT 2000
112#define HUB_DEBOUNCE_STEP 25 113#define HUB_DEBOUNCE_STEP 25
113#define HUB_DEBOUNCE_STABLE 100 114#define HUB_DEBOUNCE_STABLE 100
114 115
@@ -127,7 +128,7 @@ static inline char *portspeed(struct usb_hub *hub, int portstatus)
127} 128}
128 129
129/* Note that hdev or one of its children must be locked! */ 130/* Note that hdev or one of its children must be locked! */
130static struct usb_hub *hdev_to_hub(struct usb_device *hdev) 131struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev)
131{ 132{
132 if (!hdev || !hdev->actconfig || !hdev->maxchild) 133 if (!hdev || !hdev->actconfig || !hdev->maxchild)
133 return NULL; 134 return NULL;
@@ -301,7 +302,7 @@ static void usb_set_lpm_parameters(struct usb_device *udev)
301 if (!udev->lpm_capable || udev->speed != USB_SPEED_SUPER) 302 if (!udev->lpm_capable || udev->speed != USB_SPEED_SUPER)
302 return; 303 return;
303 304
304 hub = hdev_to_hub(udev->parent); 305 hub = usb_hub_to_struct_hub(udev->parent);
305 /* It doesn't take time to transition the roothub into U0, since it 306 /* It doesn't take time to transition the roothub into U0, since it
306 * doesn't have an upstream link. 307 * doesn't have an upstream link.
307 */ 308 */
@@ -393,7 +394,7 @@ static int clear_hub_feature(struct usb_device *hdev, int feature)
393/* 394/*
394 * USB 2.0 spec Section 11.24.2.2 395 * USB 2.0 spec Section 11.24.2.2
395 */ 396 */
396static int clear_port_feature(struct usb_device *hdev, int port1, int feature) 397int usb_clear_port_feature(struct usb_device *hdev, int port1, int feature)
397{ 398{
398 return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), 399 return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
399 USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1, 400 USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port1,
@@ -586,7 +587,7 @@ static void kick_khubd(struct usb_hub *hub)
586 587
587void usb_kick_khubd(struct usb_device *hdev) 588void usb_kick_khubd(struct usb_device *hdev)
588{ 589{
589 struct usb_hub *hub = hdev_to_hub(hdev); 590 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
590 591
591 if (hub) 592 if (hub)
592 kick_khubd(hub); 593 kick_khubd(hub);
@@ -608,7 +609,7 @@ void usb_wakeup_notification(struct usb_device *hdev,
608 if (!hdev) 609 if (!hdev)
609 return; 610 return;
610 611
611 hub = hdev_to_hub(hdev); 612 hub = usb_hub_to_struct_hub(hdev);
612 if (hub) { 613 if (hub) {
613 set_bit(portnum, hub->wakeup_bits); 614 set_bit(portnum, hub->wakeup_bits);
614 kick_khubd(hub); 615 kick_khubd(hub);
@@ -727,11 +728,16 @@ int usb_hub_set_port_power(struct usb_device *hdev, int port1,
727 bool set) 728 bool set)
728{ 729{
729 int ret; 730 int ret;
731 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
732 struct usb_port *port_dev = hub->ports[port1 - 1];
730 733
731 if (set) 734 if (set)
732 ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); 735 ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
733 else 736 else
734 ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER); 737 ret = usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
738
739 if (!ret)
740 port_dev->power_is_on = set;
735 return ret; 741 return ret;
736} 742}
737 743
@@ -811,7 +817,11 @@ static unsigned hub_power_on(struct usb_hub *hub, bool do_delay)
811 dev_dbg(hub->intfdev, "trying to enable port power on " 817 dev_dbg(hub->intfdev, "trying to enable port power on "
812 "non-switchable hub\n"); 818 "non-switchable hub\n");
813 for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++) 819 for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++)
814 set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER); 820 if (hub->ports[port1 - 1]->power_is_on)
821 set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER);
822 else
823 usb_clear_port_feature(hub->hdev, port1,
824 USB_PORT_FEAT_POWER);
815 825
816 /* Wait at least 100 msec for power to become stable */ 826 /* Wait at least 100 msec for power to become stable */
817 delay = max(pgood_delay, (unsigned) 100); 827 delay = max(pgood_delay, (unsigned) 100);
@@ -905,7 +915,7 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
905 if (hub_is_superspeed(hub->hdev)) 915 if (hub_is_superspeed(hub->hdev))
906 ret = hub_usb3_port_disable(hub, port1); 916 ret = hub_usb3_port_disable(hub, port1);
907 else 917 else
908 ret = clear_port_feature(hdev, port1, 918 ret = usb_clear_port_feature(hdev, port1,
909 USB_PORT_FEAT_ENABLE); 919 USB_PORT_FEAT_ENABLE);
910 } 920 }
911 if (ret) 921 if (ret)
@@ -954,7 +964,7 @@ int usb_remove_device(struct usb_device *udev)
954 964
955 if (!udev->parent) /* Can't remove a root hub */ 965 if (!udev->parent) /* Can't remove a root hub */
956 return -EINVAL; 966 return -EINVAL;
957 hub = hdev_to_hub(udev->parent); 967 hub = usb_hub_to_struct_hub(udev->parent);
958 intf = to_usb_interface(hub->intfdev); 968 intf = to_usb_interface(hub->intfdev);
959 969
960 usb_autopm_get_interface(intf); 970 usb_autopm_get_interface(intf);
@@ -1086,7 +1096,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
1086 * Do not disable USB3 protocol ports. 1096 * Do not disable USB3 protocol ports.
1087 */ 1097 */
1088 if (!hub_is_superspeed(hdev)) { 1098 if (!hub_is_superspeed(hdev)) {
1089 clear_port_feature(hdev, port1, 1099 usb_clear_port_feature(hdev, port1,
1090 USB_PORT_FEAT_ENABLE); 1100 USB_PORT_FEAT_ENABLE);
1091 portstatus &= ~USB_PORT_STAT_ENABLE; 1101 portstatus &= ~USB_PORT_STAT_ENABLE;
1092 } else { 1102 } else {
@@ -1098,18 +1108,18 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
1098 /* Clear status-change flags; we'll debounce later */ 1108 /* Clear status-change flags; we'll debounce later */
1099 if (portchange & USB_PORT_STAT_C_CONNECTION) { 1109 if (portchange & USB_PORT_STAT_C_CONNECTION) {
1100 need_debounce_delay = true; 1110 need_debounce_delay = true;
1101 clear_port_feature(hub->hdev, port1, 1111 usb_clear_port_feature(hub->hdev, port1,
1102 USB_PORT_FEAT_C_CONNECTION); 1112 USB_PORT_FEAT_C_CONNECTION);
1103 } 1113 }
1104 if (portchange & USB_PORT_STAT_C_ENABLE) { 1114 if (portchange & USB_PORT_STAT_C_ENABLE) {
1105 need_debounce_delay = true; 1115 need_debounce_delay = true;
1106 clear_port_feature(hub->hdev, port1, 1116 usb_clear_port_feature(hub->hdev, port1,
1107 USB_PORT_FEAT_C_ENABLE); 1117 USB_PORT_FEAT_C_ENABLE);
1108 } 1118 }
1109 if ((portchange & USB_PORT_STAT_C_BH_RESET) && 1119 if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
1110 hub_is_superspeed(hub->hdev)) { 1120 hub_is_superspeed(hub->hdev)) {
1111 need_debounce_delay = true; 1121 need_debounce_delay = true;
1112 clear_port_feature(hub->hdev, port1, 1122 usb_clear_port_feature(hub->hdev, port1,
1113 USB_PORT_FEAT_C_BH_PORT_RESET); 1123 USB_PORT_FEAT_C_BH_PORT_RESET);
1114 } 1124 }
1115 /* We can forget about a "removed" device when there's a 1125 /* We can forget about a "removed" device when there's a
@@ -1143,10 +1153,16 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
1143 set_bit(port1, hub->change_bits); 1153 set_bit(port1, hub->change_bits);
1144 1154
1145 } else if (udev->persist_enabled) { 1155 } else if (udev->persist_enabled) {
1156 struct usb_port *port_dev = hub->ports[port1 - 1];
1157
1146#ifdef CONFIG_PM 1158#ifdef CONFIG_PM
1147 udev->reset_resume = 1; 1159 udev->reset_resume = 1;
1148#endif 1160#endif
1149 set_bit(port1, hub->change_bits); 1161 /* Don't set the change_bits when the device
1162 * was powered off.
1163 */
1164 if (port_dev->power_is_on)
1165 set_bit(port1, hub->change_bits);
1150 1166
1151 } else { 1167 } else {
1152 /* The power session is gone; tell khubd */ 1168 /* The power session is gone; tell khubd */
@@ -1712,7 +1728,7 @@ static int
1712hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) 1728hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
1713{ 1729{
1714 struct usb_device *hdev = interface_to_usbdev (intf); 1730 struct usb_device *hdev = interface_to_usbdev (intf);
1715 struct usb_hub *hub = hdev_to_hub(hdev); 1731 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
1716 1732
1717 /* assert ifno == 0 (part of hub spec) */ 1733 /* assert ifno == 0 (part of hub spec) */
1718 switch (code) { 1734 switch (code) {
@@ -1758,7 +1774,7 @@ static int find_port_owner(struct usb_device *hdev, unsigned port1,
1758 /* This assumes that devices not managed by the hub driver 1774 /* This assumes that devices not managed by the hub driver
1759 * will always have maxchild equal to 0. 1775 * will always have maxchild equal to 0.
1760 */ 1776 */
1761 *ppowner = &(hdev_to_hub(hdev)->ports[port1 - 1]->port_owner); 1777 *ppowner = &(usb_hub_to_struct_hub(hdev)->ports[port1 - 1]->port_owner);
1762 return 0; 1778 return 0;
1763} 1779}
1764 1780
@@ -1795,7 +1811,7 @@ int usb_hub_release_port(struct usb_device *hdev, unsigned port1,
1795 1811
1796void usb_hub_release_all_ports(struct usb_device *hdev, struct dev_state *owner) 1812void usb_hub_release_all_ports(struct usb_device *hdev, struct dev_state *owner)
1797{ 1813{
1798 struct usb_hub *hub = hdev_to_hub(hdev); 1814 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
1799 int n; 1815 int n;
1800 1816
1801 for (n = 0; n < hdev->maxchild; n++) { 1817 for (n = 0; n < hdev->maxchild; n++) {
@@ -1812,13 +1828,13 @@ bool usb_device_is_owned(struct usb_device *udev)
1812 1828
1813 if (udev->state == USB_STATE_NOTATTACHED || !udev->parent) 1829 if (udev->state == USB_STATE_NOTATTACHED || !udev->parent)
1814 return false; 1830 return false;
1815 hub = hdev_to_hub(udev->parent); 1831 hub = usb_hub_to_struct_hub(udev->parent);
1816 return !!hub->ports[udev->portnum - 1]->port_owner; 1832 return !!hub->ports[udev->portnum - 1]->port_owner;
1817} 1833}
1818 1834
1819static void recursively_mark_NOTATTACHED(struct usb_device *udev) 1835static void recursively_mark_NOTATTACHED(struct usb_device *udev)
1820{ 1836{
1821 struct usb_hub *hub = hdev_to_hub(udev); 1837 struct usb_hub *hub = usb_hub_to_struct_hub(udev);
1822 int i; 1838 int i;
1823 1839
1824 for (i = 0; i < udev->maxchild; ++i) { 1840 for (i = 0; i < udev->maxchild; ++i) {
@@ -1987,7 +2003,7 @@ static void hub_free_dev(struct usb_device *udev)
1987void usb_disconnect(struct usb_device **pdev) 2003void usb_disconnect(struct usb_device **pdev)
1988{ 2004{
1989 struct usb_device *udev = *pdev; 2005 struct usb_device *udev = *pdev;
1990 struct usb_hub *hub = hdev_to_hub(udev); 2006 struct usb_hub *hub = usb_hub_to_struct_hub(udev);
1991 int i; 2007 int i;
1992 2008
1993 /* mark the device as inactive, so any further urb submissions for 2009 /* mark the device as inactive, so any further urb submissions for
@@ -2015,13 +2031,16 @@ void usb_disconnect(struct usb_device **pdev)
2015 usb_hcd_synchronize_unlinks(udev); 2031 usb_hcd_synchronize_unlinks(udev);
2016 2032
2017 if (udev->parent) { 2033 if (udev->parent) {
2018 struct usb_port *port_dev = 2034 struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
2019 hdev_to_hub(udev->parent)->ports[udev->portnum - 1]; 2035 struct usb_port *port_dev = hub->ports[udev->portnum - 1];
2020 2036
2021 sysfs_remove_link(&udev->dev.kobj, "port"); 2037 sysfs_remove_link(&udev->dev.kobj, "port");
2022 sysfs_remove_link(&port_dev->dev.kobj, "device"); 2038 sysfs_remove_link(&port_dev->dev.kobj, "device");
2023 2039
2024 pm_runtime_put(&port_dev->dev); 2040 if (!port_dev->did_runtime_put)
2041 pm_runtime_put(&port_dev->dev);
2042 else
2043 port_dev->did_runtime_put = false;
2025 } 2044 }
2026 2045
2027 usb_remove_ep_devs(&udev->ep0); 2046 usb_remove_ep_devs(&udev->ep0);
@@ -2210,7 +2229,7 @@ static void set_usb_port_removable(struct usb_device *udev)
2210 if (!hdev) 2229 if (!hdev)
2211 return; 2230 return;
2212 2231
2213 hub = hdev_to_hub(udev->parent); 2232 hub = usb_hub_to_struct_hub(udev->parent);
2214 2233
2215 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); 2234 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
2216 2235
@@ -2318,8 +2337,8 @@ int usb_new_device(struct usb_device *udev)
2318 2337
2319 /* Create link files between child device and usb port device. */ 2338 /* Create link files between child device and usb port device. */
2320 if (udev->parent) { 2339 if (udev->parent) {
2321 struct usb_port *port_dev = 2340 struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
2322 hdev_to_hub(udev->parent)->ports[udev->portnum - 1]; 2341 struct usb_port *port_dev = hub->ports[udev->portnum - 1];
2323 2342
2324 err = sysfs_create_link(&udev->dev.kobj, 2343 err = sysfs_create_link(&udev->dev.kobj,
2325 &port_dev->dev.kobj, "port"); 2344 &port_dev->dev.kobj, "port");
@@ -2567,14 +2586,14 @@ static void hub_port_finish_reset(struct usb_hub *hub, int port1,
2567 /* FALL THROUGH */ 2586 /* FALL THROUGH */
2568 case -ENOTCONN: 2587 case -ENOTCONN:
2569 case -ENODEV: 2588 case -ENODEV:
2570 clear_port_feature(hub->hdev, 2589 usb_clear_port_feature(hub->hdev,
2571 port1, USB_PORT_FEAT_C_RESET); 2590 port1, USB_PORT_FEAT_C_RESET);
2572 if (hub_is_superspeed(hub->hdev)) { 2591 if (hub_is_superspeed(hub->hdev)) {
2573 clear_port_feature(hub->hdev, port1, 2592 usb_clear_port_feature(hub->hdev, port1,
2574 USB_PORT_FEAT_C_BH_PORT_RESET); 2593 USB_PORT_FEAT_C_BH_PORT_RESET);
2575 clear_port_feature(hub->hdev, port1, 2594 usb_clear_port_feature(hub->hdev, port1,
2576 USB_PORT_FEAT_C_PORT_LINK_STATE); 2595 USB_PORT_FEAT_C_PORT_LINK_STATE);
2577 clear_port_feature(hub->hdev, port1, 2596 usb_clear_port_feature(hub->hdev, port1,
2578 USB_PORT_FEAT_C_CONNECTION); 2597 USB_PORT_FEAT_C_CONNECTION);
2579 } 2598 }
2580 if (udev) 2599 if (udev)
@@ -2748,10 +2767,10 @@ static int check_port_resume_type(struct usb_device *udev,
2748 2767
2749 /* Late port handoff can set status-change bits */ 2768 /* Late port handoff can set status-change bits */
2750 if (portchange & USB_PORT_STAT_C_CONNECTION) 2769 if (portchange & USB_PORT_STAT_C_CONNECTION)
2751 clear_port_feature(hub->hdev, port1, 2770 usb_clear_port_feature(hub->hdev, port1,
2752 USB_PORT_FEAT_C_CONNECTION); 2771 USB_PORT_FEAT_C_CONNECTION);
2753 if (portchange & USB_PORT_STAT_C_ENABLE) 2772 if (portchange & USB_PORT_STAT_C_ENABLE)
2754 clear_port_feature(hub->hdev, port1, 2773 usb_clear_port_feature(hub->hdev, port1,
2755 USB_PORT_FEAT_C_ENABLE); 2774 USB_PORT_FEAT_C_ENABLE);
2756 } 2775 }
2757 2776
@@ -2852,7 +2871,9 @@ EXPORT_SYMBOL_GPL(usb_enable_ltm);
2852 */ 2871 */
2853int usb_port_suspend(struct usb_device *udev, pm_message_t msg) 2872int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
2854{ 2873{
2855 struct usb_hub *hub = hdev_to_hub(udev->parent); 2874 struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
2875 struct usb_port *port_dev = hub->ports[udev->portnum - 1];
2876 enum pm_qos_flags_status pm_qos_stat;
2856 int port1 = udev->portnum; 2877 int port1 = udev->portnum;
2857 int status; 2878 int status;
2858 2879
@@ -2945,6 +2966,21 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
2945 udev->port_is_suspended = 1; 2966 udev->port_is_suspended = 1;
2946 msleep(10); 2967 msleep(10);
2947 } 2968 }
2969
2970 /*
2971 * Check whether current status meets the requirement of
2972 * usb port power off mechanism
2973 */
2974 pm_qos_stat = dev_pm_qos_flags(&port_dev->dev,
2975 PM_QOS_FLAG_NO_POWER_OFF);
2976 if (!udev->do_remote_wakeup
2977 && pm_qos_stat != PM_QOS_FLAGS_ALL
2978 && udev->persist_enabled
2979 && !status) {
2980 pm_runtime_put_sync(&port_dev->dev);
2981 port_dev->did_runtime_put = true;
2982 }
2983
2948 usb_mark_last_busy(hub->hdev); 2984 usb_mark_last_busy(hub->hdev);
2949 return status; 2985 return status;
2950} 2986}
@@ -3070,11 +3106,22 @@ static int finish_port_resume(struct usb_device *udev)
3070 */ 3106 */
3071int usb_port_resume(struct usb_device *udev, pm_message_t msg) 3107int usb_port_resume(struct usb_device *udev, pm_message_t msg)
3072{ 3108{
3073 struct usb_hub *hub = hdev_to_hub(udev->parent); 3109 struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
3110 struct usb_port *port_dev = hub->ports[udev->portnum - 1];
3074 int port1 = udev->portnum; 3111 int port1 = udev->portnum;
3075 int status; 3112 int status;
3076 u16 portchange, portstatus; 3113 u16 portchange, portstatus;
3077 3114
3115 if (port_dev->did_runtime_put) {
3116 status = pm_runtime_get_sync(&port_dev->dev);
3117 port_dev->did_runtime_put = false;
3118 if (status < 0) {
3119 dev_dbg(&udev->dev, "can't resume usb port, status %d\n",
3120 status);
3121 return status;
3122 }
3123 }
3124
3078 /* Skip the initial Clear-Suspend step for a remote wakeup */ 3125 /* Skip the initial Clear-Suspend step for a remote wakeup */
3079 status = hub_port_status(hub, port1, &portstatus, &portchange); 3126 status = hub_port_status(hub, port1, &portstatus, &portchange);
3080 if (status == 0 && !port_is_suspended(hub, portstatus)) 3127 if (status == 0 && !port_is_suspended(hub, portstatus))
@@ -3088,7 +3135,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
3088 if (hub_is_superspeed(hub->hdev)) 3135 if (hub_is_superspeed(hub->hdev))
3089 status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U0); 3136 status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U0);
3090 else 3137 else
3091 status = clear_port_feature(hub->hdev, 3138 status = usb_clear_port_feature(hub->hdev,
3092 port1, USB_PORT_FEAT_SUSPEND); 3139 port1, USB_PORT_FEAT_SUSPEND);
3093 if (status) { 3140 if (status) {
3094 dev_dbg(hub->intfdev, "can't resume port %d, status %d\n", 3141 dev_dbg(hub->intfdev, "can't resume port %d, status %d\n",
@@ -3114,11 +3161,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
3114 udev->port_is_suspended = 0; 3161 udev->port_is_suspended = 0;
3115 if (hub_is_superspeed(hub->hdev)) { 3162 if (hub_is_superspeed(hub->hdev)) {
3116 if (portchange & USB_PORT_STAT_C_LINK_STATE) 3163 if (portchange & USB_PORT_STAT_C_LINK_STATE)
3117 clear_port_feature(hub->hdev, port1, 3164 usb_clear_port_feature(hub->hdev, port1,
3118 USB_PORT_FEAT_C_PORT_LINK_STATE); 3165 USB_PORT_FEAT_C_PORT_LINK_STATE);
3119 } else { 3166 } else {
3120 if (portchange & USB_PORT_STAT_C_SUSPEND) 3167 if (portchange & USB_PORT_STAT_C_SUSPEND)
3121 clear_port_feature(hub->hdev, port1, 3168 usb_clear_port_feature(hub->hdev, port1,
3122 USB_PORT_FEAT_C_SUSPEND); 3169 USB_PORT_FEAT_C_SUSPEND);
3123 } 3170 }
3124 } 3171 }
@@ -3174,7 +3221,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
3174 3221
3175int usb_port_resume(struct usb_device *udev, pm_message_t msg) 3222int usb_port_resume(struct usb_device *udev, pm_message_t msg)
3176{ 3223{
3177 struct usb_hub *hub = hdev_to_hub(udev->parent); 3224 struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
3178 int port1 = udev->portnum; 3225 int port1 = udev->portnum;
3179 int status; 3226 int status;
3180 u16 portchange, portstatus; 3227 u16 portchange, portstatus;
@@ -3753,7 +3800,7 @@ EXPORT_SYMBOL_GPL(usb_enable_ltm);
3753 * every 25ms for transient disconnects. When the port status has been 3800 * every 25ms for transient disconnects. When the port status has been
3754 * unchanged for 100ms it returns the port status. 3801 * unchanged for 100ms it returns the port status.
3755 */ 3802 */
3756static int hub_port_debounce(struct usb_hub *hub, int port1) 3803int hub_port_debounce(struct usb_hub *hub, int port1, bool must_be_connected)
3757{ 3804{
3758 int ret; 3805 int ret;
3759 int total_time, stable_time = 0; 3806 int total_time, stable_time = 0;
@@ -3767,7 +3814,9 @@ static int hub_port_debounce(struct usb_hub *hub, int port1)
3767 3814
3768 if (!(portchange & USB_PORT_STAT_C_CONNECTION) && 3815 if (!(portchange & USB_PORT_STAT_C_CONNECTION) &&
3769 (portstatus & USB_PORT_STAT_CONNECTION) == connection) { 3816 (portstatus & USB_PORT_STAT_CONNECTION) == connection) {
3770 stable_time += HUB_DEBOUNCE_STEP; 3817 if (!must_be_connected ||
3818 (connection == USB_PORT_STAT_CONNECTION))
3819 stable_time += HUB_DEBOUNCE_STEP;
3771 if (stable_time >= HUB_DEBOUNCE_STABLE) 3820 if (stable_time >= HUB_DEBOUNCE_STABLE)
3772 break; 3821 break;
3773 } else { 3822 } else {
@@ -3776,7 +3825,7 @@ static int hub_port_debounce(struct usb_hub *hub, int port1)
3776 } 3825 }
3777 3826
3778 if (portchange & USB_PORT_STAT_C_CONNECTION) { 3827 if (portchange & USB_PORT_STAT_C_CONNECTION) {
3779 clear_port_feature(hub->hdev, port1, 3828 usb_clear_port_feature(hub->hdev, port1,
3780 USB_PORT_FEAT_C_CONNECTION); 3829 USB_PORT_FEAT_C_CONNECTION);
3781 } 3830 }
3782 3831
@@ -4288,7 +4337,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
4288 4337
4289 if (portchange & (USB_PORT_STAT_C_CONNECTION | 4338 if (portchange & (USB_PORT_STAT_C_CONNECTION |
4290 USB_PORT_STAT_C_ENABLE)) { 4339 USB_PORT_STAT_C_ENABLE)) {
4291 status = hub_port_debounce(hub, port1); 4340 status = hub_port_debounce_be_stable(hub, port1);
4292 if (status < 0) { 4341 if (status < 0) {
4293 if (printk_ratelimit()) 4342 if (printk_ratelimit())
4294 dev_err(hub_dev, "connect-debounce failed, " 4343 dev_err(hub_dev, "connect-debounce failed, "
@@ -4467,7 +4516,7 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
4467 if (!hub_is_superspeed(hdev)) { 4516 if (!hub_is_superspeed(hdev)) {
4468 if (!(portchange & USB_PORT_STAT_C_SUSPEND)) 4517 if (!(portchange & USB_PORT_STAT_C_SUSPEND))
4469 return 0; 4518 return 0;
4470 clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND); 4519 usb_clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND);
4471 } else { 4520 } else {
4472 if (!udev || udev->state != USB_STATE_SUSPENDED || 4521 if (!udev || udev->state != USB_STATE_SUSPENDED ||
4473 (portstatus & USB_PORT_STAT_LINK_STATE) != 4522 (portstatus & USB_PORT_STAT_LINK_STATE) !=
@@ -4595,7 +4644,7 @@ static void hub_events(void)
4595 continue; 4644 continue;
4596 4645
4597 if (portchange & USB_PORT_STAT_C_CONNECTION) { 4646 if (portchange & USB_PORT_STAT_C_CONNECTION) {
4598 clear_port_feature(hdev, i, 4647 usb_clear_port_feature(hdev, i,
4599 USB_PORT_FEAT_C_CONNECTION); 4648 USB_PORT_FEAT_C_CONNECTION);
4600 connect_change = 1; 4649 connect_change = 1;
4601 } 4650 }
@@ -4606,7 +4655,7 @@ static void hub_events(void)
4606 "port %d enable change, " 4655 "port %d enable change, "
4607 "status %08x\n", 4656 "status %08x\n",
4608 i, portstatus); 4657 i, portstatus);
4609 clear_port_feature(hdev, i, 4658 usb_clear_port_feature(hdev, i,
4610 USB_PORT_FEAT_C_ENABLE); 4659 USB_PORT_FEAT_C_ENABLE);
4611 4660
4612 /* 4661 /*
@@ -4637,7 +4686,7 @@ static void hub_events(void)
4637 4686
4638 dev_dbg(hub_dev, "over-current change on port " 4687 dev_dbg(hub_dev, "over-current change on port "
4639 "%d\n", i); 4688 "%d\n", i);
4640 clear_port_feature(hdev, i, 4689 usb_clear_port_feature(hdev, i,
4641 USB_PORT_FEAT_C_OVER_CURRENT); 4690 USB_PORT_FEAT_C_OVER_CURRENT);
4642 msleep(100); /* Cool down */ 4691 msleep(100); /* Cool down */
4643 hub_power_on(hub, true); 4692 hub_power_on(hub, true);
@@ -4651,7 +4700,7 @@ static void hub_events(void)
4651 dev_dbg (hub_dev, 4700 dev_dbg (hub_dev,
4652 "reset change on port %d\n", 4701 "reset change on port %d\n",
4653 i); 4702 i);
4654 clear_port_feature(hdev, i, 4703 usb_clear_port_feature(hdev, i,
4655 USB_PORT_FEAT_C_RESET); 4704 USB_PORT_FEAT_C_RESET);
4656 } 4705 }
4657 if ((portchange & USB_PORT_STAT_C_BH_RESET) && 4706 if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
@@ -4659,18 +4708,18 @@ static void hub_events(void)
4659 dev_dbg(hub_dev, 4708 dev_dbg(hub_dev,
4660 "warm reset change on port %d\n", 4709 "warm reset change on port %d\n",
4661 i); 4710 i);
4662 clear_port_feature(hdev, i, 4711 usb_clear_port_feature(hdev, i,
4663 USB_PORT_FEAT_C_BH_PORT_RESET); 4712 USB_PORT_FEAT_C_BH_PORT_RESET);
4664 } 4713 }
4665 if (portchange & USB_PORT_STAT_C_LINK_STATE) { 4714 if (portchange & USB_PORT_STAT_C_LINK_STATE) {
4666 clear_port_feature(hub->hdev, i, 4715 usb_clear_port_feature(hub->hdev, i,
4667 USB_PORT_FEAT_C_PORT_LINK_STATE); 4716 USB_PORT_FEAT_C_PORT_LINK_STATE);
4668 } 4717 }
4669 if (portchange & USB_PORT_STAT_C_CONFIG_ERROR) { 4718 if (portchange & USB_PORT_STAT_C_CONFIG_ERROR) {
4670 dev_warn(hub_dev, 4719 dev_warn(hub_dev,
4671 "config error on port %d\n", 4720 "config error on port %d\n",
4672 i); 4721 i);
4673 clear_port_feature(hub->hdev, i, 4722 usb_clear_port_feature(hub->hdev, i,
4674 USB_PORT_FEAT_C_PORT_CONFIG_ERROR); 4723 USB_PORT_FEAT_C_PORT_CONFIG_ERROR);
4675 } 4724 }
4676 4725
@@ -4954,7 +5003,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
4954 dev_dbg(&udev->dev, "%s for root hub!\n", __func__); 5003 dev_dbg(&udev->dev, "%s for root hub!\n", __func__);
4955 return -EISDIR; 5004 return -EISDIR;
4956 } 5005 }
4957 parent_hub = hdev_to_hub(parent_hdev); 5006 parent_hub = usb_hub_to_struct_hub(parent_hdev);
4958 5007
4959 /* Disable LPM and LTM while we reset the device and reinstall the alt 5008 /* Disable LPM and LTM while we reset the device and reinstall the alt
4960 * settings. Device-initiated LPM settings, and system exit latency 5009 * settings. Device-initiated LPM settings, and system exit latency
@@ -5210,7 +5259,7 @@ EXPORT_SYMBOL_GPL(usb_queue_reset_device);
5210struct usb_device *usb_hub_find_child(struct usb_device *hdev, 5259struct usb_device *usb_hub_find_child(struct usb_device *hdev,
5211 int port1) 5260 int port1)
5212{ 5261{
5213 struct usb_hub *hub = hdev_to_hub(hdev); 5262 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
5214 5263
5215 if (port1 < 1 || port1 > hdev->maxchild) 5264 if (port1 < 1 || port1 > hdev->maxchild)
5216 return NULL; 5265 return NULL;
@@ -5227,7 +5276,7 @@ EXPORT_SYMBOL_GPL(usb_hub_find_child);
5227void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1, 5276void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1,
5228 enum usb_port_connect_type type) 5277 enum usb_port_connect_type type)
5229{ 5278{
5230 struct usb_hub *hub = hdev_to_hub(hdev); 5279 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
5231 5280
5232 hub->ports[port1 - 1]->connect_type = type; 5281 hub->ports[port1 - 1]->connect_type = type;
5233} 5282}
@@ -5243,7 +5292,7 @@ void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1,
5243enum usb_port_connect_type 5292enum usb_port_connect_type
5244usb_get_hub_port_connect_type(struct usb_device *hdev, int port1) 5293usb_get_hub_port_connect_type(struct usb_device *hdev, int port1)
5245{ 5294{
5246 struct usb_hub *hub = hdev_to_hub(hdev); 5295 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
5247 5296
5248 return hub->ports[port1 - 1]->connect_type; 5297 return hub->ports[port1 - 1]->connect_type;
5249} 5298}
@@ -5301,7 +5350,7 @@ void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
5301acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev, 5350acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev,
5302 int port1) 5351 int port1)
5303{ 5352{
5304 struct usb_hub *hub = hdev_to_hub(hdev); 5353 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
5305 5354
5306 return DEVICE_ACPI_HANDLE(&hub->ports[port1 - 1]->dev); 5355 return DEVICE_ACPI_HANDLE(&hub->ports[port1 - 1]->dev);
5307} 5356}
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 452e5cd7b249..80ab9ee07017 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -80,6 +80,8 @@ struct usb_hub {
80 * @port_owner: port's owner 80 * @port_owner: port's owner
81 * @connect_type: port's connect type 81 * @connect_type: port's connect type
82 * @portnum: port index num based one 82 * @portnum: port index num based one
83 * @power_is_on: port's power state
84 * @did_runtime_put: port has done pm_runtime_put().
83 */ 85 */
84struct usb_port { 86struct usb_port {
85 struct usb_device *child; 87 struct usb_device *child;
@@ -87,6 +89,8 @@ struct usb_port {
87 struct dev_state *port_owner; 89 struct dev_state *port_owner;
88 enum usb_port_connect_type connect_type; 90 enum usb_port_connect_type connect_type;
89 u8 portnum; 91 u8 portnum;
92 unsigned power_is_on:1;
93 unsigned did_runtime_put:1;
90}; 94};
91 95
92#define to_usb_port(_dev) \ 96#define to_usb_port(_dev) \
@@ -98,4 +102,21 @@ extern void usb_hub_remove_port_device(struct usb_hub *hub,
98 int port1); 102 int port1);
99extern int usb_hub_set_port_power(struct usb_device *hdev, 103extern int usb_hub_set_port_power(struct usb_device *hdev,
100 int port1, bool set); 104 int port1, bool set);
105extern struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev);
106extern int hub_port_debounce(struct usb_hub *hub, int port1,
107 bool must_be_connected);
108extern int usb_clear_port_feature(struct usb_device *hdev,
109 int port1, int feature);
110
111static inline int hub_port_debounce_be_connected(struct usb_hub *hub,
112 int port1)
113{
114 return hub_port_debounce(hub, port1, true);
115}
116
117static inline int hub_port_debounce_be_stable(struct usb_hub *hub,
118 int port1)
119{
120 return hub_port_debounce(hub, port1, false);
121}
101 122
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index d288dfed6ccf..280433d80887 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -77,10 +77,36 @@ static int usb_port_runtime_resume(struct device *dev)
77 struct usb_port *port_dev = to_usb_port(dev); 77 struct usb_port *port_dev = to_usb_port(dev);
78 struct usb_device *hdev = to_usb_device(dev->parent->parent); 78 struct usb_device *hdev = to_usb_device(dev->parent->parent);
79 struct usb_interface *intf = to_usb_interface(dev->parent); 79 struct usb_interface *intf = to_usb_interface(dev->parent);
80 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
81 int port1 = port_dev->portnum;
80 int retval; 82 int retval;
81 83
84 if (!hub)
85 return -EINVAL;
86
82 usb_autopm_get_interface(intf); 87 usb_autopm_get_interface(intf);
83 retval = usb_hub_set_port_power(hdev, port_dev->portnum, true); 88 set_bit(port1, hub->busy_bits);
89
90 retval = usb_hub_set_port_power(hdev, port1, true);
91 if (port_dev->child && !retval) {
92 /*
93 * Wait for usb hub port to be reconnected in order to make
94 * the resume procedure successful.
95 */
96 retval = hub_port_debounce_be_connected(hub, port1);
97 if (retval < 0) {
98 dev_dbg(&port_dev->dev, "can't get reconnection after setting port power on, status %d\n",
99 retval);
100 goto out;
101 }
102 usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);
103
104 /* Set return value to 0 if debounce successful */
105 retval = 0;
106 }
107
108out:
109 clear_bit(port1, hub->busy_bits);
84 usb_autopm_put_interface(intf); 110 usb_autopm_put_interface(intf);
85 return retval; 111 return retval;
86} 112}
@@ -90,14 +116,23 @@ static int usb_port_runtime_suspend(struct device *dev)
90 struct usb_port *port_dev = to_usb_port(dev); 116 struct usb_port *port_dev = to_usb_port(dev);
91 struct usb_device *hdev = to_usb_device(dev->parent->parent); 117 struct usb_device *hdev = to_usb_device(dev->parent->parent);
92 struct usb_interface *intf = to_usb_interface(dev->parent); 118 struct usb_interface *intf = to_usb_interface(dev->parent);
119 struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
120 int port1 = port_dev->portnum;
93 int retval; 121 int retval;
94 122
123 if (!hub)
124 return -EINVAL;
125
95 if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF) 126 if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF)
96 == PM_QOS_FLAGS_ALL) 127 == PM_QOS_FLAGS_ALL)
97 return -EAGAIN; 128 return -EAGAIN;
98 129
99 usb_autopm_get_interface(intf); 130 usb_autopm_get_interface(intf);
100 retval = usb_hub_set_port_power(hdev, port_dev->portnum, false); 131 set_bit(port1, hub->busy_bits);
132 retval = usb_hub_set_port_power(hdev, port1, false);
133 usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
134 usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);
135 clear_bit(port1, hub->busy_bits);
101 usb_autopm_put_interface(intf); 136 usb_autopm_put_interface(intf);
102 return retval; 137 return retval;
103} 138}
@@ -130,6 +165,7 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
130 165
131 hub->ports[port1 - 1] = port_dev; 166 hub->ports[port1 - 1] = port_dev;
132 port_dev->portnum = port1; 167 port_dev->portnum = port1;
168 port_dev->power_is_on = true;
133 port_dev->dev.parent = hub->intfdev; 169 port_dev->dev.parent = hub->intfdev;
134 port_dev->dev.groups = port_dev_group; 170 port_dev->dev.groups = port_dev_group;
135 port_dev->dev.type = &usb_port_device_type; 171 port_dev->dev.type = &usb_port_device_type;