[RFC 2/2] xhci: Report USB 2.1 link status for L1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



USB 2.1 devices can go into a lower power link state, L1.  When they are
active, they are in the L0 state.  The L1 transition can be purely
driven by software, or some USB host controllers (including some xHCI
1.0 hosts) allow the host hardware to track idleness and automatically
place a port into L1.

The USB 2.1 Link Power Management ECN gives a way for USB 2.1 hubs that
support LPM to report that a port is in L1.  The port status bit 5 will
be set when the port is in L1.  The xHCI host reports the root port as
being in 'U2' when the devices is in L1, and as being in 'U0' when the
port is active (in L0).

Translate the xHCI USB 2.1 link status into the format external hubs
use, and pass the L1 status up to the USB core and tools like lsusb.

Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
---
 drivers/usb/host/xhci-hub.c |   15 ++++++++++++---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 83fc636..93f3fdf 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -461,8 +461,15 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array,
 	}
 }
 
+/* Updates Link Status for USB 2.1 port */
+static void xhci_hub_report_usb2_link_state(u32 *status, u32 status_reg)
+{
+	if ((status_reg & PORT_PLS_MASK) == XDEV_U2)
+		*status |= USB_PORT_STAT_L1;
+}
+
 /* Updates Link Status for super Speed port */
-static void xhci_hub_report_link_state(u32 *status, u32 status_reg)
+static void xhci_hub_report_usb3_link_state(u32 *status, u32 status_reg)
 {
 	u32 pls = status_reg & PORT_PLS_MASK;
 
@@ -631,14 +638,16 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
 		else
 			status |= USB_PORT_STAT_POWER;
 	}
-	/* Update Port Link State for super speed ports*/
+	/* Update Port Link State */
 	if (hcd->speed == HCD_USB3) {
-		xhci_hub_report_link_state(&status, raw_port_status);
+		xhci_hub_report_usb3_link_state(&status, raw_port_status);
 		/*
 		 * Verify if all USB3 Ports Have entered U0 already.
 		 * Delete Compliance Mode Timer if so.
 		 */
 		xhci_del_comp_mod_timer(xhci, raw_port_status, wIndex);
+	} else {
+		xhci_hub_report_usb2_link_state(&status, raw_port_status);
 	}
 	if (bus_state->port_c_suspend & (1 << wIndex))
 		status |= 1 << USB_PORT_FEAT_C_SUSPEND;
-- 
1.7.9

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux