diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-04-11 14:47:36 +0530 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-05-07 13:43:57 +0530 |
commit | c93d8b8c781f99d578ee499d178929323ca5cbc7 (patch) | |
tree | cd01e88038b65cf1872b0b86fb28b58a72f6c2db /arch/arc/kernel | |
parent | 9593a933d538a726b341cb06b3362d74931aa281 (diff) | |
download | blackbird-op-linux-c93d8b8c781f99d578ee499d178929323ca5cbc7.tar.gz blackbird-op-linux-c93d8b8c781f99d578ee499d178929323ca5cbc7.zip |
ARC: Allow embedded arc-intc to be properly placed in DT intc hierarchy
arc-intc is initialized in arc common code as it is applicable to all
platforms. However platforms with their own external intc still need to
refer to it for correct DT interrupt tree hierarchy setup,
e.g.
static struct of_device_id __initdata tb10x_irq_ids[] = {
{ .compatible = "snps,arc700-intc", .data = dummy_init_irq },
{ .compatible = "abilis,tb10x_ictl", .data = tb10x_init_irq },
{},
};
The fix is to use the generic irqchip framework to tie all irqchips in
a special linker section and then call irqchip_init() which calls the
DT of_irq_init() for all the intc in one go.
That way the platform code need not be aware of arc-intc at all.
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r-- | arch/arc/kernel/irq.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c index 84ce5317d9fc..dd4b7e32ad4f 100644 --- a/arch/arc/kernel/irq.c +++ b/arch/arc/kernel/irq.c @@ -11,6 +11,8 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/irqdomain.h> +#include <linux/irqchip.h> +#include "../../drivers/irqchip/irqchip.h" #include <asm/sections.h> #include <asm/irq.h> #include <asm/mach_desc.h> @@ -97,13 +99,11 @@ static const struct irq_domain_ops arc_intc_domain_ops = { static struct irq_domain *root_domain; -void __init init_onchip_IRQ(void) +static int __init +init_onchip_IRQ(struct device_node *intc, struct device_node *parent) { - struct device_node *intc = NULL; - - intc = of_find_compatible_node(NULL, NULL, "snps,arc700-intc"); - if (!intc) - panic("DeviceTree Missing incore intc\n"); + if (parent) + panic("DeviceTree incore intc not a root irq controller\n"); root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0, &arc_intc_domain_ops, NULL); @@ -113,8 +113,12 @@ void __init init_onchip_IRQ(void) /* with this we don't need to export root_domain */ irq_set_default_host(root_domain); + + return 0; } +IRQCHIP_DECLARE(arc_intc, "snps,arc700-intc", init_onchip_IRQ); + /* * Late Interrupt system init called from start_kernel for Boot CPU only * @@ -123,12 +127,13 @@ void __init init_onchip_IRQ(void) */ void __init init_IRQ(void) { - init_onchip_IRQ(); - /* Any external intc can be setup here */ if (machine_desc->init_irq) machine_desc->init_irq(); + /* process the entire interrupt tree in one go */ + irqchip_init(); + #ifdef CONFIG_SMP /* Master CPU can initialize it's side of IPI */ if (machine_desc->init_smp) |