diff options
Diffstat (limited to 'drivers/usb/core/port.c')
-rw-r--r-- | drivers/usb/core/port.c | 21 |
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)) { |