aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-integrator
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
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')
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c41
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c142
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
159static void sc_mask_irq(struct irq_data *d) 161static 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
164static void sc_unmask_irq(struct irq_data *d)
165{
166 writel(1 << d->irq, VA_IC_BASE + IRQ_ENABLE_SET);
167}
168
169static 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
176static void __init ap_init_irq(void) 167static 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
283static void ap_flash_set_vpp(int on) 266static 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 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/*