diff options
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 14 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 1 |
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) { |
445 | legacy_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 */ |