aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/port.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/port.c')
-rw-r--r--drivers/usb/core/port.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index fe1b6d0967e3..cd3f9dc24a06 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -103,16 +103,19 @@ static int usb_port_runtime_resume(struct device *dev)
103 msleep(hub_power_on_good_delay(hub)); 103 msleep(hub_power_on_good_delay(hub));
104 if (udev && !retval) { 104 if (udev && !retval) {
105 /* 105 /*
106 * Attempt to wait for usb hub port to be reconnected in order 106 * Our preference is to simply wait for the port to reconnect,
107 * to make the resume procedure successful. The device may have 107 * as that is the lowest latency method to restart the port.
108 * disconnected while the port was powered off, so ignore the 108 * However, there are cases where toggling port power results in
109 * return status. 109 * the host port and the device port getting out of sync causing
110 * a link training live lock. Upon timeout, flag the port as
111 * needing warm reset recovery (to be performed later by
112 * usb_port_resume() as requested via usb_wakeup_notification())
110 */ 113 */
111 retval = hub_port_debounce_be_connected(hub, port1); 114 if (hub_port_debounce_be_connected(hub, port1) < 0) {
112 if (retval < 0) 115 dev_dbg(&port_dev->dev, "reconnect timeout\n");
113 dev_dbg(&port_dev->dev, "can't get reconnection after setting port power on, status %d\n", 116 if (hub_is_superspeed(hdev))
114 retval); 117 set_bit(port1, hub->warm_reset_bits);
115 retval = 0; 118 }
116 119
117 /* Force the child awake to revalidate after the power loss. */ 120 /* Force the child awake to revalidate after the power loss. */
118 if (!test_and_set_bit(port1, hub->child_usage_bits)) { 121 if (!test_and_set_bit(port1, hub->child_usage_bits)) {