aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2012-06-12 22:55:46 -0400
committerShawn Guo <shawn.guo@linaro.org>2012-07-01 09:57:37 -0400
commit544496ab5cbdae312351da4c742ae70cab08dbf2 (patch)
tree4616bfbe170dcef54dc9673e69d170d04f84d1de /arch
parentf3eac29da1f6a477722b56ff00228e8a13f8f6c6 (diff)
ARM: imx: move irq_domain_add_legacy call into avic driver
Move irq_domain_add_legacy call from imx27-dt.c into avic init function and have the avic driver adopt irqdomain support for both DT and non-DT boot. Now avic init function calls irq_alloc_descs to get irq_base and adds a lenacy irqdomain with the irq_base, so that the mapping between avic irq and Linux irq number can be handled by irqdomain. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Sascha Hauer <s.hauer@pengutronix.de> Acked-by: Dong Aisheng <dong.aisheng@linaro.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-imx/imx27-dt.c15
-rw-r--r--arch/arm/plat-mxc/avic.c32
2 files changed, 25 insertions, 22 deletions
diff --git a/arch/arm/mach-imx/imx27-dt.c b/arch/arm/mach-imx/imx27-dt.c
index c734e564f204..5142ef048a60 100644
--- a/arch/arm/mach-imx/imx27-dt.c
+++ b/arch/arm/mach-imx/imx27-dt.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12#include <linux/irq.h> 12#include <linux/irq.h>
13#include <linux/irqdomain.h>
14#include <linux/of_irq.h> 13#include <linux/of_irq.h>
15#include <linux/of_platform.h> 14#include <linux/of_platform.h>
16#include <asm/mach/arch.h> 15#include <asm/mach/arch.h>
@@ -33,22 +32,8 @@ static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = {
33 { /* sentinel */ } 32 { /* sentinel */ }
34}; 33};
35 34
36static int __init imx27_avic_add_irq_domain(struct device_node *np,
37 struct device_node *interrupt_parent)
38{
39 irq_domain_add_legacy(np, 64, 0, 0, &irq_domain_simple_ops, NULL);
40 return 0;
41}
42
43static const struct of_device_id imx27_irq_match[] __initconst = {
44 { .compatible = "fsl,imx27-avic", .data = imx27_avic_add_irq_domain, },
45 { /* sentinel */ }
46};
47
48static void __init imx27_dt_init(void) 35static void __init imx27_dt_init(void)
49{ 36{
50 of_irq_init(imx27_irq_match);
51
52 of_platform_populate(NULL, of_default_bus_match_table, 37 of_platform_populate(NULL, of_default_bus_match_table,
53 imx27_auxdata_lookup, NULL); 38 imx27_auxdata_lookup, NULL);
54} 39}
diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c
index 689f81f9593b..e612cc1edede 100644
--- a/arch/arm/plat-mxc/avic.c
+++ b/arch/arm/plat-mxc/avic.c
@@ -19,7 +19,9 @@
19 19
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/irqdomain.h>
22#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/of.h>
23#include <mach/common.h> 25#include <mach/common.h>
24#include <asm/mach/irq.h> 26#include <asm/mach/irq.h>
25#include <asm/exception.h> 27#include <asm/exception.h>
@@ -50,15 +52,19 @@
50#define AVIC_NUM_IRQS 64 52#define AVIC_NUM_IRQS 64
51 53
52void __iomem *avic_base; 54void __iomem *avic_base;
55static struct irq_domain *domain;
53 56
54static u32 avic_saved_mask_reg[2]; 57static u32 avic_saved_mask_reg[2];
55 58
56#ifdef CONFIG_MXC_IRQ_PRIOR 59#ifdef CONFIG_MXC_IRQ_PRIOR
57static int avic_irq_set_priority(unsigned char irq, unsigned char prio) 60static int avic_irq_set_priority(unsigned char irq, unsigned char prio)
58{ 61{
62 struct irq_data *d = irq_get_irq_data(irq);
59 unsigned int temp; 63 unsigned int temp;
60 unsigned int mask = 0x0F << irq % 8 * 4; 64 unsigned int mask = 0x0F << irq % 8 * 4;
61 65
66 irq = d->hwirq;
67
62 if (irq >= AVIC_NUM_IRQS) 68 if (irq >= AVIC_NUM_IRQS)
63 return -EINVAL; 69 return -EINVAL;
64 70
@@ -75,8 +81,11 @@ static int avic_irq_set_priority(unsigned char irq, unsigned char prio)
75#ifdef CONFIG_FIQ 81#ifdef CONFIG_FIQ
76static int avic_set_irq_fiq(unsigned int irq, unsigned int type) 82static int avic_set_irq_fiq(unsigned int irq, unsigned int type)
77{ 83{
84 struct irq_data *d = irq_get_irq_data(irq);
78 unsigned int irqt; 85 unsigned int irqt;
79 86
87 irq = d->hwirq;
88
80 if (irq >= AVIC_NUM_IRQS) 89 if (irq >= AVIC_NUM_IRQS)
81 return -EINVAL; 90 return -EINVAL;
82 91
@@ -108,7 +117,7 @@ static void avic_irq_suspend(struct irq_data *d)
108{ 117{
109 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 118 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
110 struct irq_chip_type *ct = gc->chip_types; 119 struct irq_chip_type *ct = gc->chip_types;
111 int idx = gc->irq_base >> 5; 120 int idx = d->hwirq >> 5;
112 121
113 avic_saved_mask_reg[idx] = __raw_readl(avic_base + ct->regs.mask); 122 avic_saved_mask_reg[idx] = __raw_readl(avic_base + ct->regs.mask);
114 __raw_writel(gc->wake_active, avic_base + ct->regs.mask); 123 __raw_writel(gc->wake_active, avic_base + ct->regs.mask);
@@ -118,7 +127,7 @@ static void avic_irq_resume(struct irq_data *d)
118{ 127{
119 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 128 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
120 struct irq_chip_type *ct = gc->chip_types; 129 struct irq_chip_type *ct = gc->chip_types;
121 int idx = gc->irq_base >> 5; 130 int idx = d->hwirq >> 5;
122 131
123 __raw_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); 132 __raw_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask);
124} 133}
@@ -128,11 +137,10 @@ static void avic_irq_resume(struct irq_data *d)
128#define avic_irq_resume NULL 137#define avic_irq_resume NULL
129#endif 138#endif
130 139
131static __init void avic_init_gc(unsigned int irq_start) 140static __init void avic_init_gc(int idx, unsigned int irq_start)
132{ 141{
133 struct irq_chip_generic *gc; 142 struct irq_chip_generic *gc;
134 struct irq_chip_type *ct; 143 struct irq_chip_type *ct;
135 int idx = irq_start >> 5;
136 144
137 gc = irq_alloc_generic_chip("mxc-avic", 1, irq_start, avic_base, 145 gc = irq_alloc_generic_chip("mxc-avic", 1, irq_start, avic_base,
138 handle_level_irq); 146 handle_level_irq);
@@ -161,7 +169,7 @@ asmlinkage void __exception_irq_entry avic_handle_irq(struct pt_regs *regs)
161 if (nivector == 0xffff) 169 if (nivector == 0xffff)
162 break; 170 break;
163 171
164 handle_IRQ(nivector, regs); 172 handle_IRQ(irq_find_mapping(domain, nivector), regs);
165 } while (1); 173 } while (1);
166} 174}
167 175
@@ -172,6 +180,8 @@ asmlinkage void __exception_irq_entry avic_handle_irq(struct pt_regs *regs)
172 */ 180 */
173void __init mxc_init_irq(void __iomem *irqbase) 181void __init mxc_init_irq(void __iomem *irqbase)
174{ 182{
183 struct device_node *np;
184 int irq_base;
175 int i; 185 int i;
176 186
177 avic_base = irqbase; 187 avic_base = irqbase;
@@ -190,8 +200,16 @@ void __init mxc_init_irq(void __iomem *irqbase)
190 __raw_writel(0, avic_base + AVIC_INTTYPEH); 200 __raw_writel(0, avic_base + AVIC_INTTYPEH);
191 __raw_writel(0, avic_base + AVIC_INTTYPEL); 201 __raw_writel(0, avic_base + AVIC_INTTYPEL);
192 202
193 for (i = 0; i < AVIC_NUM_IRQS; i += 32) 203 irq_base = irq_alloc_descs(-1, 0, AVIC_NUM_IRQS, numa_node_id());
194 avic_init_gc(i); 204 WARN_ON(irq_base < 0);
205
206 np = of_find_compatible_node(NULL, NULL, "fsl,avic");
207 domain = irq_domain_add_legacy(np, AVIC_NUM_IRQS, irq_base, 0,
208 &irq_domain_simple_ops, NULL);
209 WARN_ON(!domain);
210
211 for (i = 0; i < AVIC_NUM_IRQS / 32; i++, irq_base += 32)
212 avic_init_gc(i, irq_base);
195 213
196 /* Set default priority value (0) for all IRQ's */ 214 /* Set default priority value (0) for all IRQ's */
197 for (i = 0; i < 8; i++) 215 for (i = 0; i < 8; i++)