| From 3c19b50440734aca43db7be3feea45aa431b9da4 Mon Sep 17 00:00:00 2001 |
| From: Peter Chen <peter.chen@nxp.com> |
| Date: Wed, 17 May 2017 18:32:02 +0300 |
| Subject: [PATCH 220/286] usb: host: xhci-ring: don't need to clear interrupt |
| pending for MSI enabled hcd |
| |
| According to xHCI spec Figure 30: Interrupt Throttle Flow Diagram |
| |
| If PCI Message Signaled Interrupts (MSI or MSI-X) are enabled, |
| then the assertion of the Interrupt Pending (IP) flag in Figure 30 |
| generates a PCI Dword write. The IP flag is automatically cleared |
| by the completion of the PCI write. |
| |
| the MSI enabled HCs don't need to clear interrupt pending bit, but |
| hcd->irq = 0 doesn't equal to MSI enabled HCD. At some Dual-role |
| controller software designs, it sets hcd->irq as 0 to avoid HCD |
| requesting interrupt, and they want to decide when to call usb_hcd_irq |
| by software. |
| |
| Signed-off-by: Peter Chen <peter.chen@nxp.com> |
| Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| (cherry picked from commit 6a29beef9d1b16c762e469d77e28c3de3f5c3dbb) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/usb/host/xhci-ring.c | 5 +---- |
| drivers/usb/host/xhci.c | 5 +++-- |
| include/linux/usb/hcd.h | 1 + |
| 3 files changed, 5 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/usb/host/xhci-ring.c |
| +++ b/drivers/usb/host/xhci-ring.c |
| @@ -2710,12 +2710,9 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd |
| */ |
| status |= STS_EINT; |
| writel(status, &xhci->op_regs->status); |
| - /* FIXME when MSI-X is supported and there are multiple vectors */ |
| - /* Clear the MSI-X event interrupt status */ |
| |
| - if (hcd->irq) { |
| + if (!hcd->msi_enabled) { |
| u32 irq_pending; |
| - /* Acknowledge the PCI interrupt */ |
| irq_pending = readl(&xhci->ir_set->irq_pending); |
| irq_pending |= IMAN_IP; |
| writel(irq_pending, &xhci->ir_set->irq_pending); |
| --- a/drivers/usb/host/xhci.c |
| +++ b/drivers/usb/host/xhci.c |
| @@ -401,9 +401,10 @@ static int xhci_try_enable_msi(struct us |
| /* fall back to msi*/ |
| ret = xhci_setup_msi(xhci); |
| |
| - if (!ret) |
| - /* hcd->irq is 0, we have MSI */ |
| + if (!ret) { |
| + hcd->msi_enabled = 1; |
| return 0; |
| + } |
| |
| if (!pdev->irq) { |
| xhci_err(xhci, "No msi-x/msi found and no IRQ in BIOS\n"); |
| --- a/include/linux/usb/hcd.h |
| +++ b/include/linux/usb/hcd.h |
| @@ -148,6 +148,7 @@ struct usb_hcd { |
| unsigned rh_registered:1;/* is root hub registered? */ |
| unsigned rh_pollable:1; /* may we poll the root hub? */ |
| unsigned msix_enabled:1; /* driver has MSI-X enabled? */ |
| + unsigned msi_enabled:1; /* driver has MSI enabled? */ |
| unsigned remove_phy:1; /* auto-remove USB phy */ |
| |
| /* The next flag is a stopgap, to be removed when all the HCDs |