aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hub.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2011-11-10 19:02:13 -0500
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2012-05-18 18:41:52 -0400
commit797b0ca5e6283b4cc0bdeeb0e5915f21522ba85f (patch)
treed0403d305832896a4b13a96ee43090c41d7ddc81 /drivers/usb/host/xhci-hub.c
parent33b2831ac870d50cc8e01c317b07fb1e69c13fe1 (diff)
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 <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host/xhci-hub.c')
-rw-r--r--drivers/usb/host/xhci-hub.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 89850a82d51b..2732ef660c5c 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -475,6 +475,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
475 struct xhci_bus_state *bus_state; 475 struct xhci_bus_state *bus_state;
476 u16 link_state = 0; 476 u16 link_state = 0;
477 u16 wake_mask = 0; 477 u16 wake_mask = 0;
478 u16 timeout = 0;
478 479
479 max_ports = xhci_get_ports(hcd, &port_array); 480 max_ports = xhci_get_ports(hcd, &port_array);
480 bus_state = &xhci->bus_state[hcd_index(hcd)]; 481 bus_state = &xhci->bus_state[hcd_index(hcd)];
@@ -623,6 +624,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
623 link_state = (wIndex & 0xff00) >> 3; 624 link_state = (wIndex & 0xff00) >> 3;
624 if (wValue == USB_PORT_FEAT_REMOTE_WAKE_MASK) 625 if (wValue == USB_PORT_FEAT_REMOTE_WAKE_MASK)
625 wake_mask = wIndex & 0xff00; 626 wake_mask = wIndex & 0xff00;
627 /* The MSB of wIndex is the U1/U2 timeout */
628 timeout = (wIndex & 0xff00) >> 8;
626 wIndex &= 0xff; 629 wIndex &= 0xff;
627 if (!wIndex || wIndex > max_ports) 630 if (!wIndex || wIndex > max_ports)
628 goto error; 631 goto error;
@@ -747,6 +750,22 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
747 750
748 temp = xhci_readl(xhci, port_array[wIndex]); 751 temp = xhci_readl(xhci, port_array[wIndex]);
749 break; 752 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;
750 default: 769 default:
751 goto error; 770 goto error;
752 } 771 }