diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2014-11-24 09:35:09 -0500 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-11-26 10:55:11 -0500 |
commit | 443acc4f37f61e343f3577dc28d7e7fd8b499465 (patch) | |
tree | e75db0912f5bce93d2e0bf33f7a011ba9ff372e9 /drivers/irqchip/irq-gic-v3.c | |
parent | be091d468a0a09a7f4b1645e20cd6d36a353e51a (diff) |
irqchip: GICv3: Convert to domain hierarchy
In order to start supporting stacked domains, convert the GICv3
code base to the new domain hierarchy framework, which mostly
amounts to supporting the new alloc/free callbacks.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Link: https://lkml.kernel.org/r/1416839720-18400-3-git-send-email-marc.zyngier@arm.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'drivers/irqchip/irq-gic-v3.c')
-rw-r--r-- | drivers/irqchip/irq-gic-v3.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index aa17ae805a70..4cb355aff3c6 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c | |||
@@ -594,14 +594,14 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, | |||
594 | /* PPIs */ | 594 | /* PPIs */ |
595 | if (hw < 32) { | 595 | if (hw < 32) { |
596 | irq_set_percpu_devid(irq); | 596 | irq_set_percpu_devid(irq); |
597 | irq_set_chip_and_handler(irq, &gic_chip, | 597 | irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, |
598 | handle_percpu_devid_irq); | 598 | handle_percpu_devid_irq, NULL, NULL); |
599 | set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); | 599 | set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); |
600 | } | 600 | } |
601 | /* SPIs */ | 601 | /* SPIs */ |
602 | if (hw >= 32 && hw < gic_data.irq_nr) { | 602 | if (hw >= 32 && hw < gic_data.irq_nr) { |
603 | irq_set_chip_and_handler(irq, &gic_chip, | 603 | irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data, |
604 | handle_fasteoi_irq); | 604 | handle_fasteoi_irq, NULL, NULL); |
605 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 605 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
606 | } | 606 | } |
607 | irq_set_chip_data(irq, d->host_data); | 607 | irq_set_chip_data(irq, d->host_data); |
@@ -633,9 +633,41 @@ static int gic_irq_domain_xlate(struct irq_domain *d, | |||
633 | return 0; | 633 | return 0; |
634 | } | 634 | } |
635 | 635 | ||
636 | static int gic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, | ||
637 | unsigned int nr_irqs, void *arg) | ||
638 | { | ||
639 | int i, ret; | ||
640 | irq_hw_number_t hwirq; | ||
641 | unsigned int type = IRQ_TYPE_NONE; | ||
642 | struct of_phandle_args *irq_data = arg; | ||
643 | |||
644 | ret = gic_irq_domain_xlate(domain, irq_data->np, irq_data->args, | ||
645 | irq_data->args_count, &hwirq, &type); | ||
646 | if (ret) | ||
647 | return ret; | ||
648 | |||
649 | for (i = 0; i < nr_irqs; i++) | ||
650 | gic_irq_domain_map(domain, virq + i, hwirq + i); | ||
651 | |||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | static void gic_irq_domain_free(struct irq_domain *domain, unsigned int virq, | ||
656 | unsigned int nr_irqs) | ||
657 | { | ||
658 | int i; | ||
659 | |||
660 | for (i = 0; i < nr_irqs; i++) { | ||
661 | struct irq_data *d = irq_domain_get_irq_data(domain, virq + i); | ||
662 | irq_set_handler(virq + i, NULL); | ||
663 | irq_domain_reset_irq_data(d); | ||
664 | } | ||
665 | } | ||
666 | |||
636 | static const struct irq_domain_ops gic_irq_domain_ops = { | 667 | static const struct irq_domain_ops gic_irq_domain_ops = { |
637 | .map = gic_irq_domain_map, | ||
638 | .xlate = gic_irq_domain_xlate, | 668 | .xlate = gic_irq_domain_xlate, |
669 | .alloc = gic_irq_domain_alloc, | ||
670 | .free = gic_irq_domain_free, | ||
639 | }; | 671 | }; |
640 | 672 | ||
641 | static int __init gic_of_init(struct device_node *node, struct device_node *parent) | 673 | static int __init gic_of_init(struct device_node *node, struct device_node *parent) |