aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVignesh R <vigneshr@ti.com>2017-12-29 06:41:31 -0500
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2018-01-10 06:20:32 -0500
commit09b2d20349e37a03a0951ab69524b516c8f1cc5b (patch)
tree726cacfa874758f2337fe493149b31cd0a48ccd5
parent524d59f6e30aab5b618da55e604c802ccd83e708 (diff)
PCI: dra7xx: Iterate over INTx status bits
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>
-rw-r--r--drivers/pci/dwc/pci-dra7xx.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index 3321da945f0f..8bf7c2714db6 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -257,7 +257,8 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
257 struct dra7xx_pcie *dra7xx = arg; 257 struct dra7xx_pcie *dra7xx = arg;
258 struct dw_pcie *pci = dra7xx->pci; 258 struct dw_pcie *pci = dra7xx->pci;
259 struct pcie_port *pp = &pci->pp; 259 struct pcie_port *pp = &pci->pp;
260 u32 reg; 260 unsigned long reg;
261 u32 virq, bit;
261 262
262 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI); 263 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
263 264
@@ -269,8 +270,11 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
269 case INTB: 270 case INTB:
270 case INTC: 271 case INTC:
271 case INTD: 272 case INTD:
272 generic_handle_irq(irq_find_mapping(dra7xx->irq_domain, 273 for_each_set_bit(bit, &reg, PCI_NUM_INTX) {
273 ffs(reg) - 1)); 274 virq = irq_find_mapping(dra7xx->irq_domain, bit);
275 if (virq)
276 generic_handle_irq(virq);
277 }
274 break; 278 break;
275 } 279 }
276 280