aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-04-11 05:17:36 -0400
committerVineet Gupta <vgupta@synopsys.com>2013-05-07 04:13:57 -0400
commitc93d8b8c781f99d578ee499d178929323ca5cbc7 (patch)
treecd01e88038b65cf1872b0b86fb28b58a72f6c2db /arch/arc/kernel
parent9593a933d538a726b341cb06b3362d74931aa281 (diff)
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.c21
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 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/of.h> 12#include <linux/of.h>
13#include <linux/irqdomain.h> 13#include <linux/irqdomain.h>
14#include <linux/irqchip.h>
15#include "../../drivers/irqchip/irqchip.h"
14#include <asm/sections.h> 16#include <asm/sections.h>
15#include <asm/irq.h> 17#include <asm/irq.h>
16#include <asm/mach_desc.h> 18#include <asm/mach_desc.h>
@@ -97,13 +99,11 @@ static const struct irq_domain_ops arc_intc_domain_ops = {
97 99
98static struct irq_domain *root_domain; 100static struct irq_domain *root_domain;
99 101
100void __init init_onchip_IRQ(void) 102static int __init
103init_onchip_IRQ(struct device_node *intc, struct device_node *parent)
101{ 104{
102 struct device_node *intc = NULL; 105 if (parent)
103 106 panic("DeviceTree incore intc not a root irq controller\n");
104 intc = of_find_compatible_node(NULL, NULL, "snps,arc700-intc");
105 if (!intc)
106 panic("DeviceTree Missing incore intc\n");
107 107
108 root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0, 108 root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0,
109 &arc_intc_domain_ops, NULL); 109 &arc_intc_domain_ops, NULL);
@@ -113,8 +113,12 @@ void __init init_onchip_IRQ(void)
113 113
114 /* with this we don't need to export root_domain */ 114 /* with this we don't need to export root_domain */
115 irq_set_default_host(root_domain); 115 irq_set_default_host(root_domain);
116
117 return 0;
116} 118}
117 119
120IRQCHIP_DECLARE(arc_intc, "snps,arc700-intc", init_onchip_IRQ);
121
118/* 122/*
119 * Late Interrupt system init called from start_kernel for Boot CPU only 123 * Late Interrupt system init called from start_kernel for Boot CPU only
120 * 124 *
@@ -123,12 +127,13 @@ void __init init_onchip_IRQ(void)
123 */ 127 */
124void __init init_IRQ(void) 128void __init init_IRQ(void)
125{ 129{
126 init_onchip_IRQ();
127
128 /* Any external intc can be setup here */ 130 /* Any external intc can be setup here */
129 if (machine_desc->init_irq) 131 if (machine_desc->init_irq)
130 machine_desc->init_irq(); 132 machine_desc->init_irq();
131 133
134 /* process the entire interrupt tree in one go */
135 irqchip_init();
136
132#ifdef CONFIG_SMP 137#ifdef CONFIG_SMP
133 /* Master CPU can initialize it's side of IPI */ 138 /* Master CPU can initialize it's side of IPI */
134 if (machine_desc->init_smp) 139 if (machine_desc->init_smp)