summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/xhci-ring.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index b62037bff68..ca38483c9f5 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1321,20 +1321,16 @@ static void handle_port_status(struct xhci_hcd *xhci,
}
if (DEV_SUPERSPEED(temp)) {
- xhci_dbg(xhci, "resume SS port %d\n", port_id);
+ xhci_dbg(xhci, "remote wake SS port %d\n", port_id);
+ xhci_test_and_clear_bit(xhci, port_array,
+ faked_port_index, PORT_PLC);
xhci_set_link_state(xhci, port_array, faked_port_index,
XDEV_U0);
- slot_id = xhci_find_slot_id_by_port(hcd, xhci,
- faked_port_index + 1);
- if (!slot_id) {
- xhci_dbg(xhci, "slot_id is zero\n");
- goto cleanup;
- }
- xhci_ring_device(xhci, slot_id);
- xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
- /* Clear PORT_PLC */
- xhci_test_and_clear_bit(xhci, port_array,
- faked_port_index, PORT_PLC);
+ /* Need to wait until the next link state change
+ * indicates the device is actually in U0.
+ */
+ bogus_port_status = true;
+ goto cleanup;
} else {
xhci_dbg(xhci, "resume HS port %d\n", port_id);
bus_state->resume_done[faked_port_index] = jiffies +
@@ -1345,6 +1341,15 @@ static void handle_port_status(struct xhci_hcd *xhci,
}
}
+ if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_U0 &&
+ DEV_SUPERSPEED(temp)) {
+ xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
+ slot_id = xhci_find_slot_id_by_port(hcd, xhci,
+ faked_port_index + 1);
+ if (slot_id && xhci->devs[slot_id])
+ xhci_ring_device(xhci, slot_id);
+ }
+
if (hcd->speed != HCD_USB3)
xhci_test_and_clear_bit(xhci, port_array, faked_port_index,
PORT_PLC);