summaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/pcie-mediatek.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/controller/pcie-mediatek.c')
-rw-r--r--drivers/pci/controller/pcie-mediatek.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index 23548b517..ea91d63c8 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -620,14 +620,20 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc)
if (status & MSI_STATUS){
unsigned long imsi_status;
+ /*
+ * The interrupt status can be cleared even if the
+ * MSI status remains pending. As such, given the
+ * edge-triggered interrupt type, its status should
+ * be cleared before being dispatched to the
+ * handler of the underlying device.
+ */
+ writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) {
for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) {
virq = irq_find_mapping(port->inner_domain, bit);
generic_handle_irq(virq);
}
}
- /* Clear MSI interrupt status */
- writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
}
}