aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */