Commit 306c54d0 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Greg Kroah-Hartman

usb: hcd: Try MSI interrupts on PCI devices

It appears that some platforms share same IRQ line between several devices,
some of which are EHCI and OHCI controllers. This is neither practical nor
performance-wise, especially in the case when they are supporting MSI.

In order to improve the situation try to allocate MSI and fallback to legacy
IRQ if no MSI available.
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20200702143045.23429-1-andriy.shevchenko@linux.intel.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent eed3c957
......@@ -194,20 +194,21 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id,
* make sure irq setup is not touched for xhci in generic hcd code
*/
if ((driver->flags & HCD_MASK) < HCD_USB3) {
if (!dev->irq) {
retval = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY | PCI_IRQ_MSI);
if (retval < 0) {
dev_err(&dev->dev,
"Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
pci_name(dev));
retval = -ENODEV;
goto disable_pci;
}
hcd_irq = dev->irq;
hcd_irq = pci_irq_vector(dev, 0);
}
hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev));
if (!hcd) {
retval = -ENOMEM;
goto disable_pci;
goto free_irq_vectors;
}
hcd->amd_resume_bug = (usb_hcd_amd_remote_wakeup_quirk(dev) &&
......@@ -286,6 +287,9 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id,
put_hcd:
usb_put_hcd(hcd);
free_irq_vectors:
if ((driver->flags & HCD_MASK) < HCD_USB3)
pci_free_irq_vectors(dev);
disable_pci:
pci_disable_device(dev);
dev_err(&dev->dev, "init %s fail, %d\n", pci_name(dev), retval);
......@@ -343,6 +347,8 @@ void usb_hcd_pci_remove(struct pci_dev *dev)
up_read(&companions_rwsem);
}
usb_put_hcd(hcd);
if ((hcd->driver->flags & HCD_MASK) < HCD_USB3)
pci_free_irq_vectors(dev);
pci_disable_device(dev);
}
EXPORT_SYMBOL_GPL(usb_hcd_pci_remove);
......@@ -454,7 +460,7 @@ static int suspend_common(struct device *dev, bool do_wakeup)
* synchronized here.
*/
if (!hcd->msix_enabled)
synchronize_irq(pci_dev->irq);
synchronize_irq(pci_irq_vector(pci_dev, 0));
/* Downstream ports from this root hub should already be quiesced, so
* there will be no DMA activity. Now we can shut down the upstream
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment