> Hi Yu, > > Please test this patch, and make sure that interrupts aren't registered twice. > I think this approach is better, since it creates a new quirk specifically for xhci > platform devices, so we can tell them apart from PCI devices. [Yu:] Yes. This patch is working for me. This is one clear solution. Thanks for help solute this issue. > > Sarah Sharp > > >8-------------------------------------------------------------------8< > > The xHCI platform driver calls into usb_add_hcd to register the irq for its > platform device. It does not want the xHCI generic driver to register an > interrupt for it at all. The original code did that by setting the > XHCI_BROKEN_MSI quirk, which tells the xHCI driver to not enable MSI or > MSI-X for a PCI host. > > Unfortunately, if CONFIG_PCI is enabled, and CONFIG_USB_DW3 is enabled, > the xHCI generic driver will attempt to register a legacy PCI interrupt for the > xHCI platform device in xhci_try_enable_msi(). This will result in a bogus irq > being registered, since the underlying device is a platform_device, not a > pci_device, and thus the pci_device->irq pointer will be bogus. > > Add a new quirk, XHCI_PLAT, so that the xHCI generic driver can distinguish > between a PCI device that can't handle MSI or MSI-X, and a platform device > that should not have its interrupts touched at all. > This quirk may be useful in the future, in case other corner cases like this arise. > > This patch should be backported to kernels as old as 3.9, that contain the > commit 00eed9c814cb8f281be6f0f5d8f45025dc0a97eb "USB: xhci: > correctly enable interrupts". > > Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> > Reported-by: Yu Y Wang <yu.y.wang@xxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > --- > drivers/usb/host/xhci-plat.c | 2 +- > drivers/usb/host/xhci.c | 7 ++++++- > drivers/usb/host/xhci.h | 1 + > 3 files changed, 8 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index > 51e22bf..6eca5a5 100644 > --- a/drivers/usb/host/xhci-plat.c > +++ b/drivers/usb/host/xhci-plat.c > @@ -24,7 +24,7 @@ static void xhci_plat_quirks(struct device *dev, struct > xhci_hcd *xhci) > * here that the generic code does not try to make a pci_dev from our > * dev struct in order to setup MSI > */ > - xhci->quirks |= XHCI_BROKEN_MSI; > + xhci->quirks |= XHCI_PLAT; > } > > /* called during probe() after chip reset completes */ diff --git > a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 9478caa..ead3555 > 100644 > --- a/drivers/usb/host/xhci.c > +++ b/drivers/usb/host/xhci.c > @@ -343,9 +343,14 @@ static void __maybe_unused > xhci_msix_sync_irqs(struct xhci_hcd *xhci) static int > xhci_try_enable_msi(struct usb_hcd *hcd) { > struct xhci_hcd *xhci = hcd_to_xhci(hcd); > - struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); > + struct pci_dev *pdev; > int ret; > > + /* The xhci platform device has set up IRQs through usb_add_hcd. */ > + if (xhci->quirks & XHCI_PLAT) > + return 0; > + > + pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); > /* > * Some Fresco Logic host controllers advertise MSI, but fail to > * generate interrupts. Don't even try to enable MSI. > diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index > c338741..6ab1e60 100644 > --- a/drivers/usb/host/xhci.h > +++ b/drivers/usb/host/xhci.h > @@ -1542,6 +1542,7 @@ struct xhci_hcd { > #define XHCI_SPURIOUS_REBOOT (1 << 13) > #define XHCI_COMP_MODE_QUIRK (1 << 14) > #define XHCI_AVOID_BEI (1 << 15) > +#define XHCI_PLAT (1 << 16) > unsigned int num_active_eps; > unsigned int limit_active_eps; > /* There are two roothubs to keep track of bus suspend info for */ > -- > 1.8.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html