diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2012-06-12 22:55:46 -0400 |
---|---|---|
committer | Shawn Guo <shawn.guo@linaro.org> | 2012-07-01 09:57:37 -0400 |
commit | 544496ab5cbdae312351da4c742ae70cab08dbf2 (patch) | |
tree | 4616bfbe170dcef54dc9673e69d170d04f84d1de /arch | |
parent | f3eac29da1f6a477722b56ff00228e8a13f8f6c6 (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.c | 15 | ||||
-rw-r--r-- | arch/arm/plat-mxc/avic.c | 32 |
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 | ||
36 | static 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 | |||
43 | static const struct of_device_id imx27_irq_match[] __initconst = { | ||
44 | { .compatible = "fsl,imx27-avic", .data = imx27_avic_add_irq_domain, }, | ||
45 | { /* sentinel */ } | ||
46 | }; | ||
47 | |||
48 | static void __init imx27_dt_init(void) | 35 | static 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 | ||
52 | void __iomem *avic_base; | 54 | void __iomem *avic_base; |
55 | static struct irq_domain *domain; | ||
53 | 56 | ||
54 | static u32 avic_saved_mask_reg[2]; | 57 | static u32 avic_saved_mask_reg[2]; |
55 | 58 | ||
56 | #ifdef CONFIG_MXC_IRQ_PRIOR | 59 | #ifdef CONFIG_MXC_IRQ_PRIOR |
57 | static int avic_irq_set_priority(unsigned char irq, unsigned char prio) | 60 | static 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 |
76 | static int avic_set_irq_fiq(unsigned int irq, unsigned int type) | 82 | static 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 | ||
131 | static __init void avic_init_gc(unsigned int irq_start) | 140 | static __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 | */ |
173 | void __init mxc_init_irq(void __iomem *irqbase) | 181 | void __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++) |