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

Commit 56d9bf66 authored by Sarah Sharp's avatar Sarah Sharp Committed by Jack Pham
Browse files

xhci-plat: Don't enable legacy PCI interrupts.



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 00eed9c8 "USB: xhci:
correctly enable interrupts".

Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
Reported-by: default avatarYu Y Wang <yu.y.wang@intel.com>
Tested-by: default avatarYu Y Wang <yu.y.wang@intel.com>
Reviewed-by: default avatarFelipe Balbi <balbi@ti.com>
Cc: stable@vger.kernel.org
Change-Id: I7e57f2d737f651b6a5f7a616eef591520b2f783b
Git-commit: 52fb61250a7a132b0cfb9f4a1060a1f3c49e5a25
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


[jackp@codeaurora.org: resolved merge conflicts; renumbered other XHCI
 quirk bit flags]
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent 0cabfa0f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,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;

	if (!pdata)
		return;
+6 −1
Original line number Diff line number Diff line
@@ -332,9 +332,14 @@ static void xhci_cleanup_msix(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.
+5 −4
Original line number Diff line number Diff line
@@ -1516,6 +1516,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)
/*
 * In Synopsis DWC3 controller, PORTSC register access involves multiple clock
 * domains. When the software does a PORTSC write, handshakes are needed
@@ -1530,7 +1531,7 @@ struct xhci_hcd {
 * The workaround is to give some delay (5 mac2_clk -> UTMI clock = 60 MHz ->
 * (16.66 ns x 5 = 84ns) ~100ns after writing to the PORTSC register.
 */
#define XHCI_PORTSC_DELAY	(1 << 16)
#define XHCI_PORTSC_DELAY	(1 << 17)
/*
 * In Synopsis DWC3 controller, XHCI RESET takes some time complete. If PIPE
 * RESET is not complete by the time USBCMD.RUN bit is set then HC fails to
@@ -1538,7 +1539,7 @@ struct xhci_hcd {
 *
 * The workaround is to give worst case pipe delay ~350us after resetting HC
 */
#define XHCI_RESET_DELAY	(1 << 17)
#define XHCI_RESET_DELAY	(1 << 18)
/*
 * When the Endpoint State (EP State) is not Error/Stopped, a Set TR Dequeue
 * Pointer Command must generate a Command Completion Event with the Completion
@@ -1547,8 +1548,8 @@ struct xhci_hcd {
 *
 * The workaround is to handle TRB Error and Context State Error in same way
 */
#define XHCI_TR_DEQ_ERR_QUIRK	(1 << 18)
#define XHCI_NO_SELECTIVE_SUSPEND (1 << 19)
#define XHCI_TR_DEQ_ERR_QUIRK	(1 << 19)
#define XHCI_NO_SELECTIVE_SUSPEND (1 << 20)
	unsigned int		num_active_eps;
	unsigned int		limit_active_eps;
	/* There are two roothubs to keep track of bus suspend info for */