|
@@ -475,6 +475,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|
|
struct xhci_bus_state *bus_state;
|
|
|
u16 link_state = 0;
|
|
|
u16 wake_mask = 0;
|
|
|
+ u16 timeout = 0;
|
|
|
|
|
|
max_ports = xhci_get_ports(hcd, &port_array);
|
|
|
bus_state = &xhci->bus_state[hcd_index(hcd)];
|
|
@@ -623,6 +624,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|
|
link_state = (wIndex & 0xff00) >> 3;
|
|
|
if (wValue == USB_PORT_FEAT_REMOTE_WAKE_MASK)
|
|
|
wake_mask = wIndex & 0xff00;
|
|
|
+ /* The MSB of wIndex is the U1/U2 timeout */
|
|
|
+ timeout = (wIndex & 0xff00) >> 8;
|
|
|
wIndex &= 0xff;
|
|
|
if (!wIndex || wIndex > max_ports)
|
|
|
goto error;
|
|
@@ -747,6 +750,22 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|
|
|
|
|
temp = xhci_readl(xhci, port_array[wIndex]);
|
|
|
break;
|
|
|
+ case USB_PORT_FEAT_U1_TIMEOUT:
|
|
|
+ if (hcd->speed != HCD_USB3)
|
|
|
+ goto error;
|
|
|
+ temp = xhci_readl(xhci, port_array[wIndex] + 1);
|
|
|
+ temp &= ~PORT_U1_TIMEOUT_MASK;
|
|
|
+ temp |= PORT_U1_TIMEOUT(timeout);
|
|
|
+ xhci_writel(xhci, temp, port_array[wIndex] + 1);
|
|
|
+ break;
|
|
|
+ case USB_PORT_FEAT_U2_TIMEOUT:
|
|
|
+ if (hcd->speed != HCD_USB3)
|
|
|
+ goto error;
|
|
|
+ temp = xhci_readl(xhci, port_array[wIndex] + 1);
|
|
|
+ temp &= ~PORT_U2_TIMEOUT_MASK;
|
|
|
+ temp |= PORT_U2_TIMEOUT(timeout);
|
|
|
+ xhci_writel(xhci, temp, port_array[wIndex] + 1);
|
|
|
+ break;
|
|
|
default:
|
|
|
goto error;
|
|
|
}
|