aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2011-09-23 17:19:51 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-09-26 18:51:09 -0400
commitfc71ff7583b14347fa1cb592b698f088ecff36e3 (patch)
treee10b2ea18dafac36f7da843c7d0d87cb0f2a8194
parent6fd4562178508a0949c9fdecd8558d8b10d671bd (diff)
xHCI: Check host USB2 LPM capability
Check the host's USB2 LPM capability. USB2 software LPM support is optional for xHCI 0.96 hosts. xHCI 1.0 hosts should support software LPM, and may support hardware LPM. Signed-off-by: Andiry Xu <andiry.xu@amd.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/host/xhci-ext-caps.h6
-rw-r--r--drivers/usb/host/xhci-mem.c17
-rw-r--r--drivers/usb/host/xhci.h4
3 files changed, 27 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h
index ce5c9e51748e..c7f33123d4c0 100644
--- a/drivers/usb/host/xhci-ext-caps.h
+++ b/drivers/usb/host/xhci-ext-caps.h
@@ -65,6 +65,12 @@
65/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ 65/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */
66#define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17)) 66#define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17))
67 67
68/* USB 2.0 xHCI 0.96 L1C capability - section 7.2.2.1.3.2 */
69#define XHCI_L1C (1 << 16)
70
71/* USB 2.0 xHCI 1.0 hardware LMP capability - section 7.2.2.1.3.2 */
72#define XHCI_HLC (1 << 19)
73
68/* command register values to disable interrupts and halt the HC */ 74/* command register values to disable interrupts and halt the HC */
69/* start/stop HC execution - do not write unless HC is halted*/ 75/* start/stop HC execution - do not write unless HC is halted*/
70#define XHCI_CMD_RUN (1 << 0) 76#define XHCI_CMD_RUN (1 << 0)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index bc6ec0cb3c61..9c7ddf0f3a43 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1959,6 +1959,23 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
1959 if (port_offset == 0 || (port_offset + port_count - 1) > num_ports) 1959 if (port_offset == 0 || (port_offset + port_count - 1) > num_ports)
1960 /* WTF? "Valid values are ‘1’ to MaxPorts" */ 1960 /* WTF? "Valid values are ‘1’ to MaxPorts" */
1961 return; 1961 return;
1962
1963 /* Check the host's USB2 LPM capability */
1964 if ((xhci->hci_version == 0x96) && (major_revision != 0x03) &&
1965 (temp & XHCI_L1C)) {
1966 xhci_dbg(xhci, "xHCI 0.96: support USB2 software lpm\n");
1967 xhci->sw_lpm_support = 1;
1968 }
1969
1970 if ((xhci->hci_version >= 0x100) && (major_revision != 0x03)) {
1971 xhci_dbg(xhci, "xHCI 1.0: support USB2 software lpm\n");
1972 xhci->sw_lpm_support = 1;
1973 if (temp & XHCI_HLC) {
1974 xhci_dbg(xhci, "xHCI 1.0: support USB2 hardware lpm\n");
1975 xhci->hw_lpm_support = 1;
1976 }
1977 }
1978
1962 port_offset--; 1979 port_offset--;
1963 for (i = port_offset; i < (port_offset + port_count); i++) { 1980 for (i = port_offset; i < (port_offset + port_count); i++) {
1964 /* Duplicate entry. Ignore the port if the revisions differ. */ 1981 /* Duplicate entry. Ignore the port if the revisions differ. */
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index fa921cbbe872..8673f985046e 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1459,6 +1459,10 @@ struct xhci_hcd {
1459 /* Array of pointers to USB 2.0 PORTSC registers */ 1459 /* Array of pointers to USB 2.0 PORTSC registers */
1460 __le32 __iomem **usb2_ports; 1460 __le32 __iomem **usb2_ports;
1461 unsigned int num_usb2_ports; 1461 unsigned int num_usb2_ports;
1462 /* support xHCI 0.96 spec USB2 software LPM */
1463 unsigned sw_lpm_support:1;
1464 /* support xHCI 1.0 spec USB2 hardware LPM */
1465 unsigned hw_lpm_support:1;
1462}; 1466};
1463 1467
1464/* convert between an HCD pointer and the corresponding EHCI_HCD */ 1468/* convert between an HCD pointer and the corresponding EHCI_HCD */