aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2014-11-24 09:35:18 -0500
committerJason Cooper <jason@lakedaemon.net>2014-11-26 10:55:15 -0500
commitda33f31de3e1eebb198109c1cccdc3a094e369c4 (patch)
tree8f98c92f8f2a11c40d631e2e1a3f8d9617962b4e /drivers/irqchip
parent4c21f3c26ecc25c5520628eef8e900a36e6c6ab4 (diff)
irqchip: GICv3: ITS: plug ITS init into main GICv3 code
As the ITS is always a subsystem if GICv3, its probing/init is driven by the main GICv3 code. Plug that code in (guarded by a config option). Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Link: https://lkml.kernel.org/r/1416839720-18400-12-git-send-email-marc.zyngier@arm.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/irq-gic-v3.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 43e57da0d80e..1a146ccee701 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -76,9 +76,6 @@ static inline void __iomem *gic_dist_base(struct irq_data *d)
76 if (d->hwirq <= 1023) /* SPI -> dist_base */ 76 if (d->hwirq <= 1023) /* SPI -> dist_base */
77 return gic_data.dist_base; 77 return gic_data.dist_base;
78 78
79 if (d->hwirq >= 8192)
80 BUG(); /* LPI Detected!!! */
81
82 return NULL; 79 return NULL;
83} 80}
84 81
@@ -276,11 +273,11 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
276 do { 273 do {
277 irqnr = gic_read_iar(); 274 irqnr = gic_read_iar();
278 275
279 if (likely(irqnr > 15 && irqnr < 1020)) { 276 if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
280 int err; 277 int err;
281 err = handle_domain_irq(gic_data.domain, irqnr, regs); 278 err = handle_domain_irq(gic_data.domain, irqnr, regs);
282 if (err) { 279 if (err) {
283 WARN_ONCE(true, "Unexpected SPI received!\n"); 280 WARN_ONCE(true, "Unexpected interrupt received!\n");
284 gic_write_eoir(irqnr); 281 gic_write_eoir(irqnr);
285 } 282 }
286 continue; 283 continue;
@@ -393,6 +390,11 @@ static void gic_cpu_sys_reg_init(void)
393 gic_write_grpen1(1); 390 gic_write_grpen1(1);
394} 391}
395 392
393static int gic_dist_supports_lpis(void)
394{
395 return !!(readl_relaxed(gic_data.dist_base + GICD_TYPER) & GICD_TYPER_LPIS);
396}
397
396static void gic_cpu_init(void) 398static void gic_cpu_init(void)
397{ 399{
398 void __iomem *rbase; 400 void __iomem *rbase;
@@ -407,6 +409,10 @@ static void gic_cpu_init(void)
407 409
408 gic_cpu_config(rbase, gic_redist_wait_for_rwp); 410 gic_cpu_config(rbase, gic_redist_wait_for_rwp);
409 411
412 /* Give LPIs a spin */
413 if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
414 its_cpu_init();
415
410 /* initialise system registers */ 416 /* initialise system registers */
411 gic_cpu_sys_reg_init(); 417 gic_cpu_sys_reg_init();
412} 418}
@@ -593,12 +599,21 @@ static struct irq_chip gic_chip = {
593 .irq_set_affinity = gic_set_affinity, 599 .irq_set_affinity = gic_set_affinity,
594}; 600};
595 601
602#define GIC_ID_NR (1U << gic_data.rdists.id_bits)
603
596static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, 604static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
597 irq_hw_number_t hw) 605 irq_hw_number_t hw)
598{ 606{
599 /* SGIs are private to the core kernel */ 607 /* SGIs are private to the core kernel */
600 if (hw < 16) 608 if (hw < 16)
601 return -EPERM; 609 return -EPERM;
610 /* Nothing here */
611 if (hw >= gic_data.irq_nr && hw < 8192)
612 return -EPERM;
613 /* Off limits */
614 if (hw >= GIC_ID_NR)
615 return -EPERM;
616
602 /* PPIs */ 617 /* PPIs */
603 if (hw < 32) { 618 if (hw < 32) {
604 irq_set_percpu_devid(irq); 619 irq_set_percpu_devid(irq);
@@ -612,7 +627,15 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
612 handle_fasteoi_irq, NULL, NULL); 627 handle_fasteoi_irq, NULL, NULL);
613 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 628 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
614 } 629 }
615 irq_set_chip_data(irq, d->host_data); 630 /* LPIs */
631 if (hw >= 8192 && hw < GIC_ID_NR) {
632 if (!gic_dist_supports_lpis())
633 return -EPERM;
634 irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
635 handle_fasteoi_irq, NULL, NULL);
636 set_irq_flags(irq, IRQF_VALID);
637 }
638
616 return 0; 639 return 0;
617} 640}
618 641
@@ -633,6 +656,9 @@ static int gic_irq_domain_xlate(struct irq_domain *d,
633 case 1: /* PPI */ 656 case 1: /* PPI */
634 *out_hwirq = intspec[1] + 16; 657 *out_hwirq = intspec[1] + 16;
635 break; 658 break;
659 case GIC_IRQ_TYPE_LPI: /* LPI */
660 *out_hwirq = intspec[1];
661 break;
636 default: 662 default:
637 return -EINVAL; 663 return -EINVAL;
638 } 664 }
@@ -759,6 +785,9 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
759 785
760 set_handle_irq(gic_handle_irq); 786 set_handle_irq(gic_handle_irq);
761 787
788 if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
789 its_init(node, &gic_data.rdists, gic_data.domain);
790
762 gic_smp_init(); 791 gic_smp_init();
763 gic_dist_init(); 792 gic_dist_init();
764 gic_cpu_init(); 793 gic_cpu_init();