aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mti-malta
diff options
context:
space:
mode:
authorJeffrey Deans <jeffrey.deans@imgtec.com>2014-07-17 04:20:58 -0400
committerRalf Baechle <ralf@linux-mips.org>2014-08-01 18:06:41 -0400
commit1c772b5664d9efa8d8d25b69b4ea8ae8996d6153 (patch)
tree9ff73849a38884773d291383298263d5e0b7d624 /arch/mips/mti-malta
parent31521a7a64bc5df5202e479ee7ba8133993ab32a (diff)
MIPS: Malta: Fix dispatching of GIC interrupts
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@imgtec.com> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/7377/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mti-malta')
-rw-r--r--arch/mips/mti-malta/malta-int.c25
1 files 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];
42 42
43static DEFINE_RAW_SPINLOCK(mips_irq_lock); 43static DEFINE_RAW_SPINLOCK(mips_irq_lock);
44 44
45#ifdef CONFIG_MIPS_GIC_IPI
46DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS);
47#endif
48
45static inline int mips_pcibios_iack(void) 49static inline int mips_pcibios_iack(void)
46{ 50{
47 int irq; 51 int irq;
@@ -125,16 +129,22 @@ static void malta_hw0_irqdispatch(void)
125 129
126static void malta_ipi_irqdispatch(void) 130static void malta_ipi_irqdispatch(void)
127{ 131{
128 int irq; 132#ifdef CONFIG_MIPS_GIC_IPI
133 unsigned long irq;
134 DECLARE_BITMAP(pending, GIC_NUM_INTRS);
129 135
130 if (gic_compare_int()) 136 gic_get_int_mask(pending, ipi_ints);
131 do_IRQ(MIPS_GIC_IRQ_BASE); 137
138 irq = find_first_bit(pending, GIC_NUM_INTRS);
132 139
133 irq = gic_get_int(); 140 while (irq < GIC_NUM_INTRS) {
134 if (irq < 0) 141 do_IRQ(MIPS_GIC_IRQ_BASE + irq);
135 return; /* interrupt has already been cleared */
136 142
137 do_IRQ(MIPS_GIC_IRQ_BASE + irq); 143 irq = find_next_bit(pending, GIC_NUM_INTRS, irq + 1);
144 }
145#endif
146 if (gic_compare_int())
147 do_IRQ(MIPS_GIC_IRQ_BASE);
138} 148}
139 149
140static void corehi_irqdispatch(void) 150static void corehi_irqdispatch(void)
@@ -429,6 +439,7 @@ static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin)
429 gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; 439 gic_intr_map[intr].trigtype = GIC_TRIG_EDGE;
430 gic_intr_map[intr].flags = 0; 440 gic_intr_map[intr].flags = 0;
431 ipi_map[cpu] |= (1 << (cpupin + 2)); 441 ipi_map[cpu] |= (1 << (cpupin + 2));
442 bitmap_set(ipi_ints, intr, 1);
432} 443}
433 444
434static void __init fill_ipi_map(void) 445static void __init fill_ipi_map(void)