diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 4bc6f4201340f3dbad8a5da35f5fe60d963e3b4b..ad89a6d4111b45e0c048ee437ffd391f5af846e0 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -1179,6 +1179,39 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, break; } + /* + * For xHCI 1.1 according to section 4.19.1.2.4.1 a + * root hub port's transition to compliance mode upon + * detecting LFPS timeout may be controlled by an + * Compliance Transition Enabled (CTE) flag (not + * software visible). This flag is set by writing 0xA + * to PORTSC PLS field which will allow transition to + * compliance mode the next time LFPS timeout is + * encountered. A warm reset will clear it. + * + * The CTE flag is only supported if the HCCPARAMS2 CTC + * flag is set, otherwise, the compliance substate is + * automatically entered as on 1.0 and prior. + */ + if (link_state == USB_SS_PORT_LS_COMP_MOD) { + if (!HCC2_CTC(xhci->hcc_params2)) { + xhci_dbg(xhci, "CTC flag is 0, port already supports entering compliance mode\n"); + break; + } + + if ((temp & PORT_CONNECT)) { + xhci_warn(xhci, "Can't set compliance mode when port is connected\n"); + goto error; + } + + xhci_dbg(xhci, "Enable compliance mode transition for port %d\n", + wIndex); + xhci_set_link_state(xhci, port_array, wIndex, + link_state); + temp = readl(port_array[wIndex]); + break; + } + /* Software should not attempt to set * port link state above '3' (U3) and the port * must be enabled.