diff options
Diffstat (limited to 'drivers/usb/host/xhci-hub.c')
| -rw-r--r-- | drivers/usb/host/xhci-hub.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 2a90229be7a6..72ebbc908e19 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -388,7 +388,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) trace_xhci_stop_device(virt_dev); - cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); + cmd = xhci_alloc_command(xhci, true, GFP_NOIO); if (!cmd) return -ENOMEM; @@ -404,8 +404,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) if (GET_EP_CTX_STATE(ep_ctx) != EP_STATE_RUNNING) continue; - command = xhci_alloc_command(xhci, false, false, - GFP_NOWAIT); + command = xhci_alloc_command(xhci, false, GFP_NOWAIT); if (!command) { spin_unlock_irqrestore(&xhci->lock, flags); ret = -ENOMEM; @@ -1077,6 +1076,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, retval = -ENODEV; break; } + trace_xhci_get_port_status(wIndex, temp); status = xhci_get_port_status(hcd, bus_state, port_array, wIndex, temp, flags); if (status == 0xffffffff) @@ -1224,17 +1224,17 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, temp = readl(port_array[wIndex]); break; } - - /* Software should not attempt to set - * port link state above '3' (U3) and the port - * must be enabled. - */ - if ((temp & PORT_PE) == 0 || - (link_state > USB_SS_PORT_LS_U3)) { - xhci_warn(xhci, "Cannot set link state.\n"); + /* Port must be enabled */ + if (!(temp & PORT_PE)) { + retval = -ENODEV; + break; + } + /* Can't set port link state above '3' (U3) */ + if (link_state > USB_SS_PORT_LS_U3) { + xhci_warn(xhci, "Cannot set port %d link state %d\n", + wIndex, link_state); goto error; } - if (link_state == USB_SS_PORT_LS_U3) { slot_id = xhci_find_slot_id_by_port(hcd, xhci, wIndex + 1); @@ -1443,6 +1443,8 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) retval = -ENODEV; break; } + trace_xhci_hub_status_data(i, temp); + if ((temp & mask) != 0 || (bus_state->port_c_suspend & 1 << i) || (bus_state->resume_done[i] && time_after_eq( @@ -1520,6 +1522,13 @@ int xhci_bus_suspend(struct usb_hcd *hcd) t2 |= PORT_WKOC_E | PORT_WKCONN_E; t2 &= ~PORT_WKDISC_E; } + + if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) && + (hcd->speed < HCD_USB3)) { + if (usb_amd_pt_check_port(hcd->self.controller, + port_index)) + t2 &= ~PORT_WAKE_BITS; + } } else t2 &= ~PORT_WAKE_BITS; |