Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3fd1ec58 authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Greg Kroah-Hartman
Browse files

usb/xhci: group MSI interrupt registration into its own function



This patch moves the complete MSI/MSI-X/Legacy dance into its own
function. There is however one difference: If the XHCI_BROKEN_MSI flag
is set then we don't free and register the irq, we simply return.
This is preparation for later PCI decouple.

Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7b720009
Loading
Loading
Loading
Loading
+42 −28
Original line number Diff line number Diff line
@@ -397,6 +397,45 @@ static int xhci_run_finished(struct xhci_hcd *xhci)
	return 0;
}

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);
	int ret;

	/*
	 * Some Fresco Logic host controllers advertise MSI, but fail to
	 * generate interrupts.  Don't even try to enable MSI.
	 */
	if (xhci->quirks & XHCI_BROKEN_MSI)
		return 0;

	/* unregister the legacy interrupt */
	if (hcd->irq)
		free_irq(hcd->irq, hcd);
	hcd->irq = -1;

	ret = xhci_setup_msix(xhci);
	if (ret)
		/* fall back to msi*/
		ret = xhci_setup_msi(xhci);

	if (!ret)
		/* hcd->irq is -1, we have MSI */
		return 0;

	/* fall back to legacy interrupt*/
	ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
			hcd->irq_descr, hcd);
	if (ret) {
		xhci_err(xhci, "request interrupt %d failed\n",
				pdev->irq);
		return ret;
	}
	hcd->irq = pdev->irq;
	return 0;
}

/*
 * Start the HC after it was halted.
 *
@@ -413,9 +452,8 @@ int xhci_run(struct usb_hcd *hcd)
{
	u32 temp;
	u64 temp_64;
	u32 ret;
	int ret;
	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
	struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);

	/* Start the xHCI host controller running only after the USB 2.0 roothub
	 * is setup.
@@ -426,34 +464,10 @@ int xhci_run(struct usb_hcd *hcd)
		return xhci_run_finished(xhci);

	xhci_dbg(xhci, "xhci_run\n");
	/* unregister the legacy interrupt */
	if (hcd->irq)
		free_irq(hcd->irq, hcd);
	hcd->irq = -1;

	/* Some Fresco Logic host controllers advertise MSI, but fail to
	 * generate interrupts.  Don't even try to enable MSI.
	 */
	if (xhci->quirks & XHCI_BROKEN_MSI)
		goto legacy_irq;

	ret = xhci_setup_msix(xhci);
	ret = xhci_try_enable_msi(hcd);
	if (ret)
		/* fall back to msi*/
		ret = xhci_setup_msi(xhci);

	if (ret) {
legacy_irq:
		/* fall back to legacy interrupt*/
		ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
					hcd->irq_descr, hcd);
		if (ret) {
			xhci_err(xhci, "request interrupt %d failed\n",
					pdev->irq);
		return ret;
		}
		hcd->irq = pdev->irq;
	}

#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
	init_timer(&xhci->event_ring_timer);