aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/irq-gic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/irqchip/irq-gic.c')
-rw-r--r--drivers/irqchip/irq-gic.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 3826698b5890..38493ff28fa5 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -270,8 +270,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
270 irqnr = irqstat & GICC_IAR_INT_ID_MASK; 270 irqnr = irqstat & GICC_IAR_INT_ID_MASK;
271 271
272 if (likely(irqnr > 15 && irqnr < 1021)) { 272 if (likely(irqnr > 15 && irqnr < 1021)) {
273 irqnr = irq_find_mapping(gic->domain, irqnr); 273 handle_domain_irq(gic->domain, irqnr, regs);
274 handle_IRQ(irqnr, regs);
275 continue; 274 continue;
276 } 275 }
277 if (irqnr < 16) { 276 if (irqnr < 16) {
@@ -298,8 +297,8 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
298 status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK); 297 status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK);
299 raw_spin_unlock(&irq_controller_lock); 298 raw_spin_unlock(&irq_controller_lock);
300 299
301 gic_irq = (status & 0x3ff); 300 gic_irq = (status & GICC_IAR_INT_ID_MASK);
302 if (gic_irq == 1023) 301 if (gic_irq == GICC_INT_SPURIOUS)
303 goto out; 302 goto out;
304 303
305 cascade_irq = irq_find_mapping(chip_data->domain, gic_irq); 304 cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
@@ -353,6 +352,21 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)
353 return mask; 352 return mask;
354} 353}
355 354
355static void gic_cpu_if_up(void)
356{
357 void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
358 u32 bypass = 0;
359
360 /*
361 * Preserve bypass disable bits to be written back later
362 */
363 bypass = readl(cpu_base + GIC_CPU_CTRL);
364 bypass &= GICC_DIS_BYPASS_MASK;
365
366 writel_relaxed(bypass | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
367}
368
369
356static void __init gic_dist_init(struct gic_chip_data *gic) 370static void __init gic_dist_init(struct gic_chip_data *gic)
357{ 371{
358 unsigned int i; 372 unsigned int i;
@@ -360,7 +374,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
360 unsigned int gic_irqs = gic->gic_irqs; 374 unsigned int gic_irqs = gic->gic_irqs;
361 void __iomem *base = gic_data_dist_base(gic); 375 void __iomem *base = gic_data_dist_base(gic);
362 376
363 writel_relaxed(0, base + GIC_DIST_CTRL); 377 writel_relaxed(GICD_DISABLE, base + GIC_DIST_CTRL);
364 378
365 /* 379 /*
366 * Set all global interrupts to this CPU only. 380 * Set all global interrupts to this CPU only.
@@ -373,7 +387,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
373 387
374 gic_dist_config(base, gic_irqs, NULL); 388 gic_dist_config(base, gic_irqs, NULL);
375 389
376 writel_relaxed(1, base + GIC_DIST_CTRL); 390 writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL);
377} 391}
378 392
379static void gic_cpu_init(struct gic_chip_data *gic) 393static void gic_cpu_init(struct gic_chip_data *gic)
@@ -400,14 +414,18 @@ static void gic_cpu_init(struct gic_chip_data *gic)
400 414
401 gic_cpu_config(dist_base, NULL); 415 gic_cpu_config(dist_base, NULL);
402 416
403 writel_relaxed(0xf0, base + GIC_CPU_PRIMASK); 417 writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK);
404 writel_relaxed(1, base + GIC_CPU_CTRL); 418 gic_cpu_if_up();
405} 419}
406 420
407void gic_cpu_if_down(void) 421void gic_cpu_if_down(void)
408{ 422{
409 void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]); 423 void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
410 writel_relaxed(0, cpu_base + GIC_CPU_CTRL); 424 u32 val = 0;
425
426 val = readl(cpu_base + GIC_CPU_CTRL);
427 val &= ~GICC_ENABLE;
428 writel_relaxed(val, cpu_base + GIC_CPU_CTRL);
411} 429}
412 430
413#ifdef CONFIG_CPU_PM 431#ifdef CONFIG_CPU_PM
@@ -467,14 +485,14 @@ static void gic_dist_restore(unsigned int gic_nr)
467 if (!dist_base) 485 if (!dist_base)
468 return; 486 return;
469 487
470 writel_relaxed(0, dist_base + GIC_DIST_CTRL); 488 writel_relaxed(GICD_DISABLE, dist_base + GIC_DIST_CTRL);
471 489
472 for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++) 490 for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
473 writel_relaxed(gic_data[gic_nr].saved_spi_conf[i], 491 writel_relaxed(gic_data[gic_nr].saved_spi_conf[i],
474 dist_base + GIC_DIST_CONFIG + i * 4); 492 dist_base + GIC_DIST_CONFIG + i * 4);
475 493
476 for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) 494 for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
477 writel_relaxed(0xa0a0a0a0, 495 writel_relaxed(GICD_INT_DEF_PRI_X4,
478 dist_base + GIC_DIST_PRI + i * 4); 496 dist_base + GIC_DIST_PRI + i * 4);
479 497
480 for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) 498 for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
@@ -485,7 +503,7 @@ static void gic_dist_restore(unsigned int gic_nr)
485 writel_relaxed(gic_data[gic_nr].saved_spi_enable[i], 503 writel_relaxed(gic_data[gic_nr].saved_spi_enable[i],
486 dist_base + GIC_DIST_ENABLE_SET + i * 4); 504 dist_base + GIC_DIST_ENABLE_SET + i * 4);
487 505
488 writel_relaxed(1, dist_base + GIC_DIST_CTRL); 506 writel_relaxed(GICD_ENABLE, dist_base + GIC_DIST_CTRL);
489} 507}
490 508
491static void gic_cpu_save(unsigned int gic_nr) 509static void gic_cpu_save(unsigned int gic_nr)
@@ -539,10 +557,11 @@ static void gic_cpu_restore(unsigned int gic_nr)
539 writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4); 557 writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
540 558
541 for (i = 0; i < DIV_ROUND_UP(32, 4); i++) 559 for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
542 writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4); 560 writel_relaxed(GICD_INT_DEF_PRI_X4,
561 dist_base + GIC_DIST_PRI + i * 4);
543 562
544 writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK); 563 writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK);
545 writel_relaxed(1, cpu_base + GIC_CPU_CTRL); 564 gic_cpu_if_up();
546} 565}
547 566
548static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) 567static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
@@ -867,7 +886,7 @@ static int gic_routable_irq_domain_xlate(struct irq_domain *d,
867 return 0; 886 return 0;
868} 887}
869 888
870const struct irq_domain_ops gic_default_routable_irq_domain_ops = { 889static const struct irq_domain_ops gic_default_routable_irq_domain_ops = {
871 .map = gic_routable_irq_domain_map, 890 .map = gic_routable_irq_domain_map,
872 .unmap = gic_routable_irq_domain_unmap, 891 .unmap = gic_routable_irq_domain_unmap,
873 .xlate = gic_routable_irq_domain_xlate, 892 .xlate = gic_routable_irq_domain_xlate,