aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2011-06-02 14:33:02 -0400
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2011-06-02 21:22:58 -0400
commitf5182b4155b9d686c5540a6822486400e34ddd98 (patch)
tree53c8a989c66da2585212a30c07015422d826d100 /drivers
parent001fd3826f4c736ce292315782d015f768399080 (diff)
xhci: Disable MSI for some Fresco Logic hosts.
Some Fresco Logic hosts, including those found in the AUAU N533V laptop, advertise MSI, but fail to actually generate MSI interrupts. Add a new xHCI quirk to skip MSI enabling for the Fresco Logic host controllers. Fresco Logic confirms that all chips with PCI vendor ID 0x1b73 and device ID 0x1000, regardless of PCI revision ID, do not support MSI. This should be backported to stable kernels as far back as 2.6.36, which was the first kernel to support MSI on xHCI hosts. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Reported-by: Sergey Galanov <sergey.e.galanov@gmail.com> Cc: stable@kernel.org
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/xhci-pci.c14
-rw-r--r--drivers/usb/host/xhci.c7
-rw-r--r--drivers/usb/host/xhci.h1
3 files changed, 20 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index c408e9f6a707..17541d09eabb 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -106,12 +106,22 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
106 106
107 /* Look for vendor-specific quirks */ 107 /* Look for vendor-specific quirks */
108 if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && 108 if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
109 pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK && 109 pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) {
110 pdev->revision == 0x0) { 110 if (pdev->revision == 0x0) {
111 xhci->quirks |= XHCI_RESET_EP_QUIRK; 111 xhci->quirks |= XHCI_RESET_EP_QUIRK;
112 xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" 112 xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
113 " endpoint cmd after reset endpoint\n"); 113 " endpoint cmd after reset endpoint\n");
114 }
115 /* Fresco Logic confirms: all revisions of this chip do not
116 * support MSI, even though some of them claim to in their PCI
117 * capabilities.
118 */
119 xhci->quirks |= XHCI_BROKEN_MSI;
120 xhci_dbg(xhci, "QUIRK: Fresco Logic revision %u "
121 "has broken MSI implementation\n",
122 pdev->revision);
114 } 123 }
124
115 if (pdev->vendor == PCI_VENDOR_ID_NEC) 125 if (pdev->vendor == PCI_VENDOR_ID_NEC)
116 xhci->quirks |= XHCI_NEC_HOST; 126 xhci->quirks |= XHCI_NEC_HOST;
117 127
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 66f3e41bba52..06e7023258d0 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -430,12 +430,19 @@ int xhci_run(struct usb_hcd *hcd)
430 free_irq(hcd->irq, hcd); 430 free_irq(hcd->irq, hcd);
431 hcd->irq = -1; 431 hcd->irq = -1;
432 432
433 /* Some Fresco Logic host controllers advertise MSI, but fail to
434 * generate interrupts. Don't even try to enable MSI.
435 */
436 if (xhci->quirks & XHCI_BROKEN_MSI)
437 goto legacy_irq;
438
433 ret = xhci_setup_msix(xhci); 439 ret = xhci_setup_msix(xhci);
434 if (ret) 440 if (ret)
435 /* fall back to msi*/ 441 /* fall back to msi*/
436 ret = xhci_setup_msi(xhci); 442 ret = xhci_setup_msi(xhci);
437 443
438 if (ret) { 444 if (ret) {
445legacy_irq:
439 /* fall back to legacy interrupt*/ 446 /* fall back to legacy interrupt*/
440 ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, 447 ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
441 hcd->irq_descr, hcd); 448 hcd->irq_descr, hcd);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index bbc1d9afb49c..7d1ea3bf5e1f 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1307,6 +1307,7 @@ struct xhci_hcd {
1307 * commands. 1307 * commands.
1308 */ 1308 */
1309#define XHCI_EP_LIMIT_QUIRK (1 << 5) 1309#define XHCI_EP_LIMIT_QUIRK (1 << 5)
1310#define XHCI_BROKEN_MSI (1 << 6)
1310 unsigned int num_active_eps; 1311 unsigned int num_active_eps;
1311 unsigned int limit_active_eps; 1312 unsigned int limit_active_eps;
1312 /* There are two roothubs to keep track of bus suspend info for */ 1313 /* There are two roothubs to keep track of bus suspend info for */