MIPS: MSI: Update MSI handling for XLP
authorJayachandran C <jchandra@broadcom.com>
Wed, 7 Jan 2015 11:28:28 +0000 (16:58 +0530)
committerRalf Baechle <ralf@linux-mips.org>
Wed, 1 Apr 2015 15:21:49 +0000 (17:21 +0200)
The per-cpu interrupt ACK using EIRR has to be done just once after
all the bits in the status register are processed.

PIC ack has to be done once in case of MSI, and for every interrupt
in case of MSI-X

Signed-off-by: Jayachandran C <jchandra@broadcom.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/8887/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/pci/msi-xlp.c

index 6a40f24c91b467564cf5d2c886ecec39df411874..3407495fcbe2fdca58976a49b4c0a9639691ae93 100644 (file)
@@ -178,13 +178,6 @@ static void xlp_msi_mask_ack(struct irq_data *d)
        else
                nlm_write_reg(md->lnkbase, PCIE_MSI_STATUS, 1u << vec);
 
-       /* Ack at eirr and PIC */
-       ack_c0_eirr(PIC_PCIE_LINK_MSI_IRQ(link));
-       if (cpu_is_xlp9xx())
-               nlm_pic_ack(md->node->picbase,
-                               PIC_9XX_IRT_PCIE_LINK_INDEX(link));
-       else
-               nlm_pic_ack(md->node->picbase, PIC_IRT_PCIE_LINK_INDEX(link));
 }
 
 static struct irq_chip xlp_msi_chip = {
@@ -230,8 +223,6 @@ static void xlp_msix_mask_ack(struct irq_data *d)
        }
        nlm_write_reg(md->lnkbase, status_reg, 1u << bit);
 
-       /* Ack at eirr and PIC */
-       ack_c0_eirr(PIC_PCIE_MSIX_IRQ(link));
        if (!cpu_is_xlp9xx())
                nlm_pic_ack(md->node->picbase,
                                PIC_IRT_PCIE_MSIX_INDEX(msixvec));
@@ -541,6 +532,14 @@ void nlm_dispatch_msi(int node, int lirq)
                do_IRQ(irqbase + i);
                status &= status - 1;
        }
+
+       /* Ack at eirr and PIC */
+       ack_c0_eirr(PIC_PCIE_LINK_MSI_IRQ(link));
+       if (cpu_is_xlp9xx())
+               nlm_pic_ack(md->node->picbase,
+                               PIC_9XX_IRT_PCIE_LINK_INDEX(link));
+       else
+               nlm_pic_ack(md->node->picbase, PIC_IRT_PCIE_LINK_INDEX(link));
 }
 
 void nlm_dispatch_msix(int node, int lirq)
@@ -567,4 +566,6 @@ void nlm_dispatch_msix(int node, int lirq)
                do_IRQ(irqbase + i);
                status &= status - 1;
        }
+       /* Ack at eirr and PIC */
+       ack_c0_eirr(PIC_PCIE_MSIX_IRQ(link));
 }