Skip to content

Commit 797b0ca

Browse files
author
Sarah Sharp
committed
xhci: Add roothub code to set U1/U2 timeouts.
USB 3.0 hubs can be put into a mode where the hub can automatically request that the link go into a deeper link power state after the link has been idle for a specified amount of time. Each of the new USB 3.0 link states (U1 and U2) have their own timeout that can be programmed per port. Change the xHCI roothub emulation code to handle the request to set the U1 and U2 timeouts. Signed-off-by: Sarah Sharp <[email protected]>
1 parent 33b2831 commit 797b0ca

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

drivers/usb/host/xhci-hub.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
475475
struct xhci_bus_state *bus_state;
476476
u16 link_state = 0;
477477
u16 wake_mask = 0;
478+
u16 timeout = 0;
478479

479480
max_ports = xhci_get_ports(hcd, &port_array);
480481
bus_state = &xhci->bus_state[hcd_index(hcd)];
@@ -623,6 +624,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
623624
link_state = (wIndex & 0xff00) >> 3;
624625
if (wValue == USB_PORT_FEAT_REMOTE_WAKE_MASK)
625626
wake_mask = wIndex & 0xff00;
627+
/* The MSB of wIndex is the U1/U2 timeout */
628+
timeout = (wIndex & 0xff00) >> 8;
626629
wIndex &= 0xff;
627630
if (!wIndex || wIndex > max_ports)
628631
goto error;
@@ -747,6 +750,22 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
747750

748751
temp = xhci_readl(xhci, port_array[wIndex]);
749752
break;
753+
case USB_PORT_FEAT_U1_TIMEOUT:
754+
if (hcd->speed != HCD_USB3)
755+
goto error;
756+
temp = xhci_readl(xhci, port_array[wIndex] + 1);
757+
temp &= ~PORT_U1_TIMEOUT_MASK;
758+
temp |= PORT_U1_TIMEOUT(timeout);
759+
xhci_writel(xhci, temp, port_array[wIndex] + 1);
760+
break;
761+
case USB_PORT_FEAT_U2_TIMEOUT:
762+
if (hcd->speed != HCD_USB3)
763+
goto error;
764+
temp = xhci_readl(xhci, port_array[wIndex] + 1);
765+
temp &= ~PORT_U2_TIMEOUT_MASK;
766+
temp |= PORT_U2_TIMEOUT(timeout);
767+
xhci_writel(xhci, temp, port_array[wIndex] + 1);
768+
break;
750769
default:
751770
goto error;
752771
}

drivers/usb/host/xhci.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,10 @@ struct xhci_op_regs {
362362
* Timeout can be up to 127us. 0xFF means an infinite timeout.
363363
*/
364364
#define PORT_U1_TIMEOUT(p) ((p) & 0xff)
365+
#define PORT_U1_TIMEOUT_MASK 0xff
365366
/* Inactivity timer value for transitions into U2 */
366367
#define PORT_U2_TIMEOUT(p) (((p) & 0xff) << 8)
368+
#define PORT_U2_TIMEOUT_MASK (0xff << 8)
367369
/* Bits 24:31 for port testing */
368370

369371
/* USB2 Protocol PORTSPMSC */

0 commit comments

Comments
 (0)