diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-19 10:32:15 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-02-19 06:11:33 -0500 |
commit | c41b16f8c9d9dc74ed5669d4a3e3d42374c9e609 (patch) | |
tree | 0e7ee2bef09e6c752cda71087795bd40f0f35177 /arch/arm/mach-integrator | |
parent | dc37c31bbfaf87118d6c827be0a38a512a40b741 (diff) |
ARM: integrator/versatile: consolidate FPGA IRQ handling code
Consolidate the FPGA IRQ handling code. Integrator/AP and Versatile
have one FPGA-based IRQ handler each. Integrator/CP has three.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-integrator')
-rw-r--r-- | arch/arm/mach-integrator/integrator_ap.c | 41 | ||||
-rw-r--r-- | arch/arm/mach-integrator/integrator_cp.c | 142 |
2 files changed, 43 insertions, 140 deletions
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 4f06b5d72489..980803ff348c 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c | |||
@@ -48,6 +48,8 @@ | |||
48 | #include <asm/mach/map.h> | 48 | #include <asm/mach/map.h> |
49 | #include <asm/mach/time.h> | 49 | #include <asm/mach/time.h> |
50 | 50 | ||
51 | #include <plat/fpga-irq.h> | ||
52 | |||
51 | #include "common.h" | 53 | #include "common.h" |
52 | 54 | ||
53 | /* | 55 | /* |
@@ -57,10 +59,10 @@ | |||
57 | * Setup a VA for the Integrator interrupt controller (for header #0, | 59 | * Setup a VA for the Integrator interrupt controller (for header #0, |
58 | * just for now). | 60 | * just for now). |
59 | */ | 61 | */ |
60 | #define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) | 62 | #define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE) |
61 | #define VA_SC_BASE IO_ADDRESS(INTEGRATOR_SC_BASE) | 63 | #define VA_SC_BASE __io_address(INTEGRATOR_SC_BASE) |
62 | #define VA_EBI_BASE IO_ADDRESS(INTEGRATOR_EBI_BASE) | 64 | #define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE) |
63 | #define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_IC) | 65 | #define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC) |
64 | 66 | ||
65 | /* | 67 | /* |
66 | * Logical Physical | 68 | * Logical Physical |
@@ -156,27 +158,14 @@ static void __init ap_map_io(void) | |||
156 | 158 | ||
157 | #define INTEGRATOR_SC_VALID_INT 0x003fffff | 159 | #define INTEGRATOR_SC_VALID_INT 0x003fffff |
158 | 160 | ||
159 | static void sc_mask_irq(struct irq_data *d) | 161 | static struct fpga_irq_data sc_irq_data = { |
160 | { | 162 | .base = VA_IC_BASE, |
161 | writel(1 << d->irq, VA_IC_BASE + IRQ_ENABLE_CLEAR); | 163 | .irq_start = 0, |
162 | } | 164 | .chip.name = "SC", |
163 | |||
164 | static void sc_unmask_irq(struct irq_data *d) | ||
165 | { | ||
166 | writel(1 << d->irq, VA_IC_BASE + IRQ_ENABLE_SET); | ||
167 | } | ||
168 | |||
169 | static struct irq_chip sc_chip = { | ||
170 | .name = "SC", | ||
171 | .irq_ack = sc_mask_irq, | ||
172 | .irq_mask = sc_mask_irq, | ||
173 | .irq_unmask = sc_unmask_irq, | ||
174 | }; | 165 | }; |
175 | 166 | ||
176 | static void __init ap_init_irq(void) | 167 | static void __init ap_init_irq(void) |
177 | { | 168 | { |
178 | unsigned int i; | ||
179 | |||
180 | /* Disable all interrupts initially. */ | 169 | /* Disable all interrupts initially. */ |
181 | /* Do the core module ones */ | 170 | /* Do the core module ones */ |
182 | writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); | 171 | writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); |
@@ -185,13 +174,7 @@ static void __init ap_init_irq(void) | |||
185 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); | 174 | writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); |
186 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); | 175 | writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); |
187 | 176 | ||
188 | for (i = 0; i < NR_IRQS; i++) { | 177 | fpga_irq_init(-1, INTEGRATOR_SC_VALID_INT, &sc_irq_data); |
189 | if (((1 << i) & INTEGRATOR_SC_VALID_INT) != 0) { | ||
190 | set_irq_chip(i, &sc_chip); | ||
191 | set_irq_handler(i, handle_level_irq); | ||
192 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | ||
193 | } | ||
194 | } | ||
195 | } | 178 | } |
196 | 179 | ||
197 | #ifdef CONFIG_PM | 180 | #ifdef CONFIG_PM |
@@ -282,7 +265,7 @@ static void ap_flash_exit(void) | |||
282 | 265 | ||
283 | static void ap_flash_set_vpp(int on) | 266 | static void ap_flash_set_vpp(int on) |
284 | { | 267 | { |
285 | unsigned long reg = on ? SC_CTRLS : SC_CTRLC; | 268 | void __iomem *reg = on ? SC_CTRLS : SC_CTRLC; |
286 | 269 | ||
287 | writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); | 270 | writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg); |
288 | } | 271 | } |
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index e6700aab849a..05da36f754dd 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/hardware/timer-sp.h> | 43 | #include <asm/hardware/timer-sp.h> |
44 | 44 | ||
45 | #include <plat/clcd.h> | 45 | #include <plat/clcd.h> |
46 | #include <plat/fpga-irq.h> | ||
46 | 47 | ||
47 | #include "common.h" | 48 | #include "common.h" |
48 | 49 | ||
@@ -51,9 +52,9 @@ | |||
51 | 52 | ||
52 | #define INTCP_PA_CLCD_BASE 0xc0000000 | 53 | #define INTCP_PA_CLCD_BASE 0xc0000000 |
53 | 54 | ||
54 | #define INTCP_VA_CIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x40) | 55 | #define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40) |
55 | #define INTCP_VA_PIC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) | 56 | #define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE) |
56 | #define INTCP_VA_SIC_BASE IO_ADDRESS(INTEGRATOR_CP_SIC_BASE) | 57 | #define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE) |
57 | 58 | ||
58 | #define INTCP_ETH_SIZE 0x10 | 59 | #define INTCP_ETH_SIZE 0x10 |
59 | 60 | ||
@@ -141,129 +142,48 @@ static void __init intcp_map_io(void) | |||
141 | iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); | 142 | iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc)); |
142 | } | 143 | } |
143 | 144 | ||
144 | #define cic_writel __raw_writel | 145 | static struct fpga_irq_data cic_irq_data = { |
145 | #define cic_readl __raw_readl | 146 | .base = INTCP_VA_CIC_BASE, |
146 | #define pic_writel __raw_writel | 147 | .irq_start = IRQ_CIC_START, |
147 | #define pic_readl __raw_readl | 148 | .chip.name = "CIC", |
148 | #define sic_writel __raw_writel | ||
149 | #define sic_readl __raw_readl | ||
150 | |||
151 | static void cic_mask_irq(struct irq_data *d) | ||
152 | { | ||
153 | unsigned int irq = d->irq - IRQ_CIC_START; | ||
154 | cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); | ||
155 | } | ||
156 | |||
157 | static void cic_unmask_irq(struct irq_data *d) | ||
158 | { | ||
159 | unsigned int irq = d->irq - IRQ_CIC_START; | ||
160 | cic_writel(1 << irq, INTCP_VA_CIC_BASE + IRQ_ENABLE_SET); | ||
161 | } | ||
162 | |||
163 | static struct irq_chip cic_chip = { | ||
164 | .name = "CIC", | ||
165 | .irq_ack = cic_mask_irq, | ||
166 | .irq_mask = cic_mask_irq, | ||
167 | .irq_unmask = cic_unmask_irq, | ||
168 | }; | 149 | }; |
169 | 150 | ||
170 | static void pic_mask_irq(struct irq_data *d) | 151 | static struct fpga_irq_data pic_irq_data = { |
171 | { | 152 | .base = INTCP_VA_PIC_BASE, |
172 | unsigned int irq = d->irq - IRQ_PIC_START; | 153 | .irq_start = IRQ_PIC_START, |
173 | pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); | 154 | .chip.name = "PIC", |
174 | } | ||
175 | |||
176 | static void pic_unmask_irq(struct irq_data *d) | ||
177 | { | ||
178 | unsigned int irq = d->irq - IRQ_PIC_START; | ||
179 | pic_writel(1 << irq, INTCP_VA_PIC_BASE + IRQ_ENABLE_SET); | ||
180 | } | ||
181 | |||
182 | static struct irq_chip pic_chip = { | ||
183 | .name = "PIC", | ||
184 | .irq_ack = pic_mask_irq, | ||
185 | .irq_mask = pic_mask_irq, | ||
186 | .irq_unmask = pic_unmask_irq, | ||
187 | }; | 155 | }; |
188 | 156 | ||
189 | static void sic_mask_irq(struct irq_data *d) | 157 | static struct fpga_irq_data sic_irq_data = { |
190 | { | 158 | .base = INTCP_VA_SIC_BASE, |
191 | unsigned int irq = d->irq - IRQ_SIC_START; | 159 | .irq_start = IRQ_SIC_START, |
192 | sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); | 160 | .chip.name = "SIC", |
193 | } | ||
194 | |||
195 | static void sic_unmask_irq(struct irq_data *d) | ||
196 | { | ||
197 | unsigned int irq = d->irq - IRQ_SIC_START; | ||
198 | sic_writel(1 << irq, INTCP_VA_SIC_BASE + IRQ_ENABLE_SET); | ||
199 | } | ||
200 | |||
201 | static struct irq_chip sic_chip = { | ||
202 | .name = "SIC", | ||
203 | .irq_ack = sic_mask_irq, | ||
204 | .irq_mask = sic_mask_irq, | ||
205 | .irq_unmask = sic_unmask_irq, | ||
206 | }; | 161 | }; |
207 | 162 | ||
208 | static void | ||
209 | sic_handle_irq(unsigned int irq, struct irq_desc *desc) | ||
210 | { | ||
211 | unsigned long status = sic_readl(INTCP_VA_SIC_BASE + IRQ_STATUS); | ||
212 | |||
213 | if (status == 0) { | ||
214 | do_bad_IRQ(irq, desc); | ||
215 | return; | ||
216 | } | ||
217 | |||
218 | do { | ||
219 | irq = ffs(status) - 1; | ||
220 | status &= ~(1 << irq); | ||
221 | |||
222 | irq += IRQ_SIC_START; | ||
223 | |||
224 | generic_handle_irq(irq); | ||
225 | } while (status); | ||
226 | } | ||
227 | |||
228 | static void __init intcp_init_irq(void) | 163 | static void __init intcp_init_irq(void) |
229 | { | 164 | { |
230 | unsigned int i; | 165 | u32 pic_mask, sic_mask; |
166 | |||
167 | pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); | ||
168 | pic_mask |= (~((~0u) << (29 - 22))) << 22; | ||
169 | sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); | ||
231 | 170 | ||
232 | /* | 171 | /* |
233 | * Disable all interrupt sources | 172 | * Disable all interrupt sources |
234 | */ | 173 | */ |
235 | pic_writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); | 174 | writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); |
236 | pic_writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); | 175 | writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); |
237 | 176 | writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); | |
238 | for (i = IRQ_PIC_START; i <= IRQ_PIC_END; i++) { | 177 | writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); |
239 | if (i == 11) | 178 | writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); |
240 | i = 22; | 179 | writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); |
241 | if (i == 29) | ||
242 | break; | ||
243 | set_irq_chip(i, &pic_chip); | ||
244 | set_irq_handler(i, handle_level_irq); | ||
245 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | ||
246 | } | ||
247 | 180 | ||
248 | cic_writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); | 181 | fpga_irq_init(-1, pic_mask, &pic_irq_data); |
249 | cic_writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); | ||
250 | 182 | ||
251 | for (i = IRQ_CIC_START; i <= IRQ_CIC_END; i++) { | 183 | fpga_irq_init(-1, ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)), |
252 | set_irq_chip(i, &cic_chip); | 184 | &cic_irq_data); |
253 | set_irq_handler(i, handle_level_irq); | ||
254 | set_irq_flags(i, IRQF_VALID); | ||
255 | } | ||
256 | |||
257 | sic_writel(0x00000fff, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); | ||
258 | sic_writel(0x00000fff, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); | ||
259 | |||
260 | for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) { | ||
261 | set_irq_chip(i, &sic_chip); | ||
262 | set_irq_handler(i, handle_level_irq); | ||
263 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | ||
264 | } | ||
265 | 185 | ||
266 | set_irq_chained_handler(IRQ_CP_CPPLDINT, sic_handle_irq); | 186 | fpga_irq_init(IRQ_CP_CPPLDINT, sic_mask, &sic_irq_data); |
267 | } | 187 | } |
268 | 188 | ||
269 | /* | 189 | /* |