xhci: Limit USB2 port wake support for AMD Promontory hosts
authorJiahau Chang <jiahau@gmail.com>
Mon, 19 Jun 2017 10:08:30 +0000 (13:08 +0300)
committerBen Hutchings <ben@decadent.org.uk>
Thu, 12 Oct 2017 14:27:10 +0000 (15:27 +0100)
commit dec08194ffeccfa1cf085906b53d301930eae18f upstream.

For AMD Promontory xHCI host, although you can disable USB 2.0 ports in
BIOS settings, those ports will be enabled anyway after you remove a
device on that port and re-plug it in again. It's a known limitation of
the chip. As a workaround we can clear the PORT_WAKE_BITS.

This will disable wake on connect, disconnect and overcurrent on
AMD Promontory USB2 ports

[checkpatch cleanup and commit message reword -Mathias]
Cc: Tsai Nicholas <nicholas.tsai@amd.com>
Signed-off-by: Jiahau Chang <Lars_Chang@asmedia.com.tw>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci.h

index d89b72c..223326b 100644 (file)
@@ -1023,6 +1023,9 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
                                t2 |= PORT_WKOC_E | PORT_WKCONN_E;
                                t2 &= ~PORT_WKDISC_E;
                        }
+                       if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) &&
+                           (hcd->speed < HCD_USB3))
+                               t2 &= ~PORT_WAKE_BITS;
                } else
                        t2 &= ~PORT_WAKE_BITS;
 
index 423700b..39cd932 100644 (file)
 #define PCI_DEVICE_ID_INTEL_APL_XHCI                   0x5aa8
 #define PCI_DEVICE_ID_INTEL_DNV_XHCI                   0x19d0
 
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_4                        0x43b9
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_3                        0x43ba
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_2                        0x43bb
+#define PCI_DEVICE_ID_AMD_PROMONTORYA_1                        0x43bc
+
 static const char hcd_name[] = "xhci_hcd";
 
 /* called after powerup, by probe or system-pm "wakeup" */
@@ -110,6 +115,13 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
        if (pdev->vendor == PCI_VENDOR_ID_AMD)
                xhci->quirks |= XHCI_TRUST_TX_LENGTH;
 
+       if ((pdev->vendor == PCI_VENDOR_ID_AMD) &&
+               ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) ||
+               (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) ||
+               (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) ||
+               (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1)))
+               xhci->quirks |= XHCI_U2_DISABLE_WAKE;
+
        if (pdev->vendor == PCI_VENDOR_ID_INTEL)
                xhci->quirks |= XHCI_INTEL_HOST;
        if (pdev->vendor == PCI_VENDOR_ID_INTEL)
index 4453f2a..307e3cc 100644 (file)
@@ -1502,6 +1502,7 @@ struct xhci_hcd {
 #define XHCI_SPURIOUS_WAKEUP   (1 << 18)
 #define XHCI_PME_STUCK_QUIRK   (1 << 20)
 #define XHCI_MISSING_CAS       (1 << 24)
+#define XHCI_U2_DISABLE_WAKE   (1 << 27)
        unsigned int            num_active_eps;
        unsigned int            limit_active_eps;
        /* There are two roothubs to keep track of bus suspend info for */