Blob Blame History Raw
From: Vignesh R <vigneshr@ti.com>
Date: Fri, 29 Dec 2017 17:11:31 +0530
Subject: PCI: dra7xx: Iterate over INTx status bits

Git-commit: 09b2d20349e37a03a0951ab69524b516c8f1cc5b
Patch-mainline: v4.16-rc1
References: fate#326536, fate#326532

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>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@suse.com>
---
 drivers/pci/dwc/pci-dra7xx.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -256,7 +256,8 @@ static irqreturn_t dra7xx_pcie_msi_irq_h
 	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);
 
@@ -268,8 +269,11 @@ static irqreturn_t dra7xx_pcie_msi_irq_h
 	case INTB:
 	case INTC:
 	case INTD:
-		generic_handle_irq(irq_find_mapping(dra7xx->irq_domain,
-						    ffs(reg)));
+		for_each_set_bit(bit, &reg, PCI_NUM_INTX) {
+			virq = irq_find_mapping(dra7xx->irq_domain, bit);
+			if (virq)
+				generic_handle_irq(virq);
+		}
 		break;
 	}