aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-integrator/integrator_cp.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-01-19 10:32:15 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-02-19 06:11:33 -0500
commitc41b16f8c9d9dc74ed5669d4a3e3d42374c9e609 (patch)
tree0e7ee2bef09e6c752cda71087795bd40f0f35177 /arch/arm/mach-integrator/integrator_cp.c
parentdc37c31bbfaf87118d6c827be0a38a512a40b741 (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/integrator_cp.c')
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c142
1 files changed, 31 insertions, 111 deletions
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 145static 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
151static 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
157static 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
163static 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
170static void pic_mask_irq(struct irq_data *d) 151static 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
176static 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
182static 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
189static void sic_mask_irq(struct irq_data *d) 157static 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
195static 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
201static 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
208static void
209sic_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
228static void __init intcp_init_irq(void) 163static 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/*