PCI: dra7xx: Iterate over INTx status bits
authorVignesh R <vigneshr@ti.com>
Fri, 29 Dec 2017 11:41:31 +0000 (17:11 +0530)
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Wed, 10 Jan 2018 11:20:32 +0000 (11:20 +0000)
It is possible that more than one legacy IRQ may be set at the same
time, therefore iterate and handle all the pending INTx interrupts
before clearing the status and exiting the IRQ handler. Otherwise, some
interrupts would be lost.

Signed-off-by: Vignesh R <vigneshr@ti.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
drivers/pci/dwc/pci-dra7xx.c

index 3321da945f0f26599ec51936cedfb978fec6a227..8bf7c2714db6c6f79b056c10154faf0e93eb6ee6 100644 (file)
@@ -257,7 +257,8 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
        struct dra7xx_pcie *dra7xx = arg;
        struct dw_pcie *pci = dra7xx->pci;
        struct pcie_port *pp = &pci->pp;
-       u32 reg;
+       unsigned long reg;
+       u32 virq, bit;
 
        reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
 
@@ -269,8 +270,11 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
        case INTB:
        case INTC:
        case INTD:
-               generic_handle_irq(irq_find_mapping(dra7xx->irq_domain,
-                                                   ffs(reg) - 1));
+               for_each_set_bit(bit, &reg, PCI_NUM_INTX) {
+                       virq = irq_find_mapping(dra7xx->irq_domain, bit);
+                       if (virq)
+                               generic_handle_irq(virq);
+               }
                break;
        }