[PATCH 6/7] MIPS: Malta: Fix dispatching of GIC interrupts

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Jeffrey Deans <jeffrey.deans@xxxxxxxxxx>

The Malta malta_ipi_irqdispatch() routine now checks only IPI interrupts
when handling IPIs. It could previously call do_IRQ() for non-IPIs, and
also call do_IRQ() with an invalid IRQ number if there were no pending
GIC interrupts when gic_get_int() was called.

Signed-off-by: Jeffrey Deans <jeffrey.deans@xxxxxxxxxx>
Signed-off-by: Markos Chandras <markos.chandras@xxxxxxxxxx>
---
 arch/mips/mti-malta/malta-int.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index 4ab919141737..e4f43baa8f67 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -42,6 +42,10 @@ static unsigned int ipi_map[NR_CPUS];
 
 static DEFINE_RAW_SPINLOCK(mips_irq_lock);
 
+#ifdef CONFIG_MIPS_GIC_IPI
+DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS);
+#endif
+
 static inline int mips_pcibios_iack(void)
 {
 	int irq;
@@ -125,16 +129,22 @@ static void malta_hw0_irqdispatch(void)
 
 static void malta_ipi_irqdispatch(void)
 {
-	int irq;
+#ifdef CONFIG_MIPS_GIC_IPI
+	unsigned long irq;
+	DECLARE_BITMAP(pending, GIC_NUM_INTRS);
 
-	if (gic_compare_int())
-		do_IRQ(MIPS_GIC_IRQ_BASE);
+	gic_get_int_mask(pending, ipi_ints);
+
+	irq = find_first_bit(pending, GIC_NUM_INTRS);
 
-	irq = gic_get_int();
-	if (irq < 0)
-		return;	 /* interrupt has already been cleared */
+	while (irq < GIC_NUM_INTRS) {
+		do_IRQ(MIPS_GIC_IRQ_BASE + irq);
 
-	do_IRQ(MIPS_GIC_IRQ_BASE + irq);
+		irq = find_next_bit(pending, GIC_NUM_INTRS, irq + 1);
+	}
+#endif
+	if (gic_compare_int())
+		do_IRQ(MIPS_GIC_IRQ_BASE);
 }
 
 static void corehi_irqdispatch(void)
@@ -429,6 +439,7 @@ static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin)
 	gic_intr_map[intr].trigtype = GIC_TRIG_EDGE;
 	gic_intr_map[intr].flags = 0;
 	ipi_map[cpu] |= (1 << (cpupin + 2));
+	bitmap_set(ipi_ints, intr, 1);
 }
 
 static void __init fill_ipi_map(void)
-- 
2.0.0



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux