aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPawel Moll <pawel.moll@arm.com>2010-11-26 07:45:43 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-11-30 08:38:57 -0500
commite6afec9b6808eff6dc392ac07c1552e87aebcdf7 (patch)
tree67ea03e347da896518f96c7611eb792bf6a9f374
parente8a7e48bb248a1196484d3f8afa53bded2b24e71 (diff)
ARM: 6496/1: GIC: Do not try to register more then NR_IRQS interrupts
This change limits number of GIC-originating interrupts to the platform maximum (defined by NR_IRQS) while still initialising all distributor registers. Signed-off-by: Pawel Moll <pawel.moll@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/common/gic.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 772f95f1aec..fea1bd7249b 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -210,7 +210,7 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
210void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, 210void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
211 unsigned int irq_start) 211 unsigned int irq_start)
212{ 212{
213 unsigned int max_irq, i; 213 unsigned int gic_irqs, irq_limit, i;
214 u32 cpumask = 1 << smp_processor_id(); 214 u32 cpumask = 1 << smp_processor_id();
215 215
216 if (gic_nr >= MAX_GIC_NR) 216 if (gic_nr >= MAX_GIC_NR)
@@ -226,47 +226,49 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
226 226
227 /* 227 /*
228 * Find out how many interrupts are supported. 228 * Find out how many interrupts are supported.
229 */
230 max_irq = readl(base + GIC_DIST_CTR) & 0x1f;
231 max_irq = (max_irq + 1) * 32;
232
233 /*
234 * The GIC only supports up to 1020 interrupt sources. 229 * The GIC only supports up to 1020 interrupt sources.
235 * Limit this to either the architected maximum, or the
236 * platform maximum.
237 */ 230 */
238 if (max_irq > max(1020, NR_IRQS)) 231 gic_irqs = readl(base + GIC_DIST_CTR) & 0x1f;
239 max_irq = max(1020, NR_IRQS); 232 gic_irqs = (gic_irqs + 1) * 32;
233 if (gic_irqs > 1020)
234 gic_irqs = 1020;
240 235
241 /* 236 /*
242 * Set all global interrupts to be level triggered, active low. 237 * Set all global interrupts to be level triggered, active low.
243 */ 238 */
244 for (i = 32; i < max_irq; i += 16) 239 for (i = 32; i < gic_irqs; i += 16)
245 writel(0, base + GIC_DIST_CONFIG + i * 4 / 16); 240 writel(0, base + GIC_DIST_CONFIG + i * 4 / 16);
246 241
247 /* 242 /*
248 * Set all global interrupts to this CPU only. 243 * Set all global interrupts to this CPU only.
249 */ 244 */
250 for (i = 32; i < max_irq; i += 4) 245 for (i = 32; i < gic_irqs; i += 4)
251 writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); 246 writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
252 247
253 /* 248 /*
254 * Set priority on all global interrupts. 249 * Set priority on all global interrupts.
255 */ 250 */
256 for (i = 32; i < max_irq; i += 4) 251 for (i = 32; i < gic_irqs; i += 4)
257 writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); 252 writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
258 253
259 /* 254 /*
260 * Disable all interrupts. Leave the PPI and SGIs alone 255 * Disable all interrupts. Leave the PPI and SGIs alone
261 * as these enables are banked registers. 256 * as these enables are banked registers.
262 */ 257 */
263 for (i = 32; i < max_irq; i += 32) 258 for (i = 32; i < gic_irqs; i += 32)
264 writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); 259 writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
265 260
266 /* 261 /*
262 * Limit number of interrupts registered to the platform maximum
263 */
264 irq_limit = gic_data[gic_nr].irq_offset + gic_irqs;
265 if (WARN_ON(irq_limit > NR_IRQS))
266 irq_limit = NR_IRQS;
267
268 /*
267 * Setup the Linux IRQ subsystem. 269 * Setup the Linux IRQ subsystem.
268 */ 270 */
269 for (i = irq_start; i < gic_data[gic_nr].irq_offset + max_irq; i++) { 271 for (i = irq_start; i < irq_limit; i++) {
270 set_irq_chip(i, &gic_chip); 272 set_irq_chip(i, &gic_chip);
271 set_irq_chip_data(i, &gic_data[gic_nr]); 273 set_irq_chip_data(i, &gic_data[gic_nr]);
272 set_irq_handler(i, handle_level_irq); 274 set_irq_handler(i, handle_level_irq);