aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2007-05-17 05:11:34 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-05-17 05:11:34 -0400
commit0f347bb9136f55ff575d55441a29e92c16e87fb0 (patch)
tree82dfc12a5178e33e26324bb3da621e40576e0879 /arch
parentf3270f6ef7d60251617f9d4c08f76ec01c647aa4 (diff)
[ARM] gic: Fix gic cascade irq handling
No need for the cascade irq function to have a "fastcall" annotation. Fix the range checking for valid IRQ numbers - comparing the value returned by the GIC with NR_IRQS is meaningless since we translate the GIC irq number to a Linux IRQ number afterwards. Check the GIC returned IRQ number is within limits first, then add the IRQ offset, and only then compare with NR_IRQS. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/common/gic.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 4deece5fbdf..2ae0bd1c907 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -125,12 +125,11 @@ static void gic_set_cpu(unsigned int irq, cpumask_t mask_val)
125} 125}
126#endif 126#endif
127 127
128static void fastcall gic_handle_cascade_irq(unsigned int irq, 128static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
129 struct irq_desc *desc)
130{ 129{
131 struct gic_chip_data *chip_data = get_irq_data(irq); 130 struct gic_chip_data *chip_data = get_irq_data(irq);
132 struct irq_chip *chip = get_irq_chip(irq); 131 struct irq_chip *chip = get_irq_chip(irq);
133 unsigned int cascade_irq; 132 unsigned int cascade_irq, gic_irq;
134 unsigned long status; 133 unsigned long status;
135 134
136 /* primary controller ack'ing */ 135 /* primary controller ack'ing */
@@ -140,16 +139,15 @@ static void fastcall gic_handle_cascade_irq(unsigned int irq,
140 status = readl(chip_data->cpu_base + GIC_CPU_INTACK); 139 status = readl(chip_data->cpu_base + GIC_CPU_INTACK);
141 spin_unlock(&irq_controller_lock); 140 spin_unlock(&irq_controller_lock);
142 141
143 cascade_irq = (status & 0x3ff); 142 gic_irq = (status & 0x3ff);
144 if (cascade_irq > 1020) 143 if (gic_irq == 1023)
145 goto out; 144 goto out;
146 if (cascade_irq < 32 || cascade_irq >= NR_IRQS) {
147 do_bad_IRQ(cascade_irq, desc);
148 goto out;
149 }
150 145
151 cascade_irq += chip_data->irq_offset; 146 cascade_irq = gic_irq + chip_data->irq_offset;
152 generic_handle_irq(cascade_irq); 147 if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS))
148 do_bad_IRQ(cascade_irq, desc);
149 else
150 generic_handle_irq(cascade_irq);
153 151
154 out: 152 out:
155 /* primary controller unmasking */ 153 /* primary controller unmasking */