aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/common/sa1111.c
diff options
context:
space:
mode:
authorEric Miao <eric.y.miao@gmail.com>2009-12-26 03:23:02 -0500
committerEric Miao <eric.y.miao@gmail.com>2010-03-01 18:40:51 -0500
commit19851c58e680f71d087b79b53edbf814193e1d33 (patch)
tree50a1c533c9953ec5e9c95d970a1e9788cf5308aa /arch/arm/common/sa1111.c
parent08fa159003aa510027951671b94aadc380ab2d2a (diff)
[ARM] sa1111: allow cascaded IRQs to be used by platforms
Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
Diffstat (limited to 'arch/arm/common/sa1111.c')
-rw-r--r--arch/arm/common/sa1111.c112
1 files changed, 88 insertions, 24 deletions
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 8ba7044c554d..a52a27c1d9be 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -35,6 +35,58 @@
35 35
36#include <asm/hardware/sa1111.h> 36#include <asm/hardware/sa1111.h>
37 37
38/* SA1111 IRQs */
39#define IRQ_GPAIN0 (0)
40#define IRQ_GPAIN1 (1)
41#define IRQ_GPAIN2 (2)
42#define IRQ_GPAIN3 (3)
43#define IRQ_GPBIN0 (4)
44#define IRQ_GPBIN1 (5)
45#define IRQ_GPBIN2 (6)
46#define IRQ_GPBIN3 (7)
47#define IRQ_GPBIN4 (8)
48#define IRQ_GPBIN5 (9)
49#define IRQ_GPCIN0 (10)
50#define IRQ_GPCIN1 (11)
51#define IRQ_GPCIN2 (12)
52#define IRQ_GPCIN3 (13)
53#define IRQ_GPCIN4 (14)
54#define IRQ_GPCIN5 (15)
55#define IRQ_GPCIN6 (16)
56#define IRQ_GPCIN7 (17)
57#define IRQ_MSTXINT (18)
58#define IRQ_MSRXINT (19)
59#define IRQ_MSSTOPERRINT (20)
60#define IRQ_TPTXINT (21)
61#define IRQ_TPRXINT (22)
62#define IRQ_TPSTOPERRINT (23)
63#define SSPXMTINT (24)
64#define SSPRCVINT (25)
65#define SSPROR (26)
66#define AUDXMTDMADONEA (32)
67#define AUDRCVDMADONEA (33)
68#define AUDXMTDMADONEB (34)
69#define AUDRCVDMADONEB (35)
70#define AUDTFSR (36)
71#define AUDRFSR (37)
72#define AUDTUR (38)
73#define AUDROR (39)
74#define AUDDTS (40)
75#define AUDRDD (41)
76#define AUDSTO (42)
77#define IRQ_USBPWR (43)
78#define IRQ_HCIM (44)
79#define IRQ_HCIBUFFACC (45)
80#define IRQ_HCIRMTWKP (46)
81#define IRQ_NHCIMFCIR (47)
82#define IRQ_USB_PORT_RESUME (48)
83#define IRQ_S0_READY_NINT (49)
84#define IRQ_S1_READY_NINT (50)
85#define IRQ_S0_CD_VALID (51)
86#define IRQ_S1_CD_VALID (52)
87#define IRQ_S0_BVD1_STSCHG (53)
88#define IRQ_S1_BVD1_STSCHG (54)
89
38extern void __init sa1110_mb_enable(void); 90extern void __init sa1110_mb_enable(void);
39 91
40/* 92/*
@@ -49,6 +101,7 @@ struct sa1111 {
49 struct clk *clk; 101 struct clk *clk;
50 unsigned long phys; 102 unsigned long phys;
51 int irq; 103 int irq;
104 int irq_base; /* base for cascaded on-chip IRQs */
52 spinlock_t lock; 105 spinlock_t lock;
53 void __iomem *base; 106 void __iomem *base;
54#ifdef CONFIG_PM 107#ifdef CONFIG_PM
@@ -152,36 +205,37 @@ static void
152sa1111_irq_handler(unsigned int irq, struct irq_desc *desc) 205sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
153{ 206{
154 unsigned int stat0, stat1, i; 207 unsigned int stat0, stat1, i;
155 void __iomem *base = get_irq_data(irq); 208 struct sa1111 *sachip = get_irq_data(irq);
209 void __iomem *mapbase = sachip->base + SA1111_INTC;
156 210
157 stat0 = sa1111_readl(base + SA1111_INTSTATCLR0); 211 stat0 = sa1111_readl(mapbase + SA1111_INTSTATCLR0);
158 stat1 = sa1111_readl(base + SA1111_INTSTATCLR1); 212 stat1 = sa1111_readl(mapbase + SA1111_INTSTATCLR1);
159 213
160 sa1111_writel(stat0, base + SA1111_INTSTATCLR0); 214 sa1111_writel(stat0, mapbase + SA1111_INTSTATCLR0);
161 215
162 desc->chip->ack(irq); 216 desc->chip->ack(irq);
163 217
164 sa1111_writel(stat1, base + SA1111_INTSTATCLR1); 218 sa1111_writel(stat1, mapbase + SA1111_INTSTATCLR1);
165 219
166 if (stat0 == 0 && stat1 == 0) { 220 if (stat0 == 0 && stat1 == 0) {
167 do_bad_IRQ(irq, desc); 221 do_bad_IRQ(irq, desc);
168 return; 222 return;
169 } 223 }
170 224
171 for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1) 225 for (i = 0; stat0; i++, stat0 >>= 1)
172 if (stat0 & 1) 226 if (stat0 & 1)
173 handle_edge_irq(i, irq_desc + i); 227 generic_handle_irq(i + sachip->irq_base);
174 228
175 for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1) 229 for (i = 32; stat1; i++, stat1 >>= 1)
176 if (stat1 & 1) 230 if (stat1 & 1)
177 handle_edge_irq(i, irq_desc + i); 231 generic_handle_irq(i + sachip->irq_base);
178 232
179 /* For level-based interrupts */ 233 /* For level-based interrupts */
180 desc->chip->unmask(irq); 234 desc->chip->unmask(irq);
181} 235}
182 236
183#define SA1111_IRQMASK_LO(x) (1 << (x - IRQ_SA1111_START)) 237#define SA1111_IRQMASK_LO(x) (1 << (x - sachip->irq_base))
184#define SA1111_IRQMASK_HI(x) (1 << (x - IRQ_SA1111_START - 32)) 238#define SA1111_IRQMASK_HI(x) (1 << (x - sachip->irq_base - 32))
185 239
186static void sa1111_ack_irq(unsigned int irq) 240static void sa1111_ack_irq(unsigned int irq)
187{ 241{
@@ -189,7 +243,8 @@ static void sa1111_ack_irq(unsigned int irq)
189 243
190static void sa1111_mask_lowirq(unsigned int irq) 244static void sa1111_mask_lowirq(unsigned int irq)
191{ 245{
192 void __iomem *mapbase = get_irq_chip_data(irq); 246 struct sa1111 *sachip = get_irq_chip_data(irq);
247 void __iomem *mapbase = sachip->base + SA1111_INTC;
193 unsigned long ie0; 248 unsigned long ie0;
194 249
195 ie0 = sa1111_readl(mapbase + SA1111_INTEN0); 250 ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
@@ -199,7 +254,8 @@ static void sa1111_mask_lowirq(unsigned int irq)
199 254
200static void sa1111_unmask_lowirq(unsigned int irq) 255static void sa1111_unmask_lowirq(unsigned int irq)
201{ 256{
202 void __iomem *mapbase = get_irq_chip_data(irq); 257 struct sa1111 *sachip = get_irq_chip_data(irq);
258 void __iomem *mapbase = sachip->base + SA1111_INTC;
203 unsigned long ie0; 259 unsigned long ie0;
204 260
205 ie0 = sa1111_readl(mapbase + SA1111_INTEN0); 261 ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
@@ -216,8 +272,9 @@ static void sa1111_unmask_lowirq(unsigned int irq)
216 */ 272 */
217static int sa1111_retrigger_lowirq(unsigned int irq) 273static int sa1111_retrigger_lowirq(unsigned int irq)
218{ 274{
275 struct sa1111 *sachip = get_irq_chip_data(irq);
276 void __iomem *mapbase = sachip->base + SA1111_INTC;
219 unsigned int mask = SA1111_IRQMASK_LO(irq); 277 unsigned int mask = SA1111_IRQMASK_LO(irq);
220 void __iomem *mapbase = get_irq_chip_data(irq);
221 unsigned long ip0; 278 unsigned long ip0;
222 int i; 279 int i;
223 280
@@ -237,8 +294,9 @@ static int sa1111_retrigger_lowirq(unsigned int irq)
237 294
238static int sa1111_type_lowirq(unsigned int irq, unsigned int flags) 295static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
239{ 296{
297 struct sa1111 *sachip = get_irq_chip_data(irq);
298 void __iomem *mapbase = sachip->base + SA1111_INTC;
240 unsigned int mask = SA1111_IRQMASK_LO(irq); 299 unsigned int mask = SA1111_IRQMASK_LO(irq);
241 void __iomem *mapbase = get_irq_chip_data(irq);
242 unsigned long ip0; 300 unsigned long ip0;
243 301
244 if (flags == IRQ_TYPE_PROBE) 302 if (flags == IRQ_TYPE_PROBE)
@@ -260,8 +318,9 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
260 318
261static int sa1111_wake_lowirq(unsigned int irq, unsigned int on) 319static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
262{ 320{
321 struct sa1111 *sachip = get_irq_chip_data(irq);
322 void __iomem *mapbase = sachip->base + SA1111_INTC;
263 unsigned int mask = SA1111_IRQMASK_LO(irq); 323 unsigned int mask = SA1111_IRQMASK_LO(irq);
264 void __iomem *mapbase = get_irq_chip_data(irq);
265 unsigned long we0; 324 unsigned long we0;
266 325
267 we0 = sa1111_readl(mapbase + SA1111_WAKEEN0); 326 we0 = sa1111_readl(mapbase + SA1111_WAKEEN0);
@@ -286,7 +345,8 @@ static struct irq_chip sa1111_low_chip = {
286 345
287static void sa1111_mask_highirq(unsigned int irq) 346static void sa1111_mask_highirq(unsigned int irq)
288{ 347{
289 void __iomem *mapbase = get_irq_chip_data(irq); 348 struct sa1111 *sachip = get_irq_chip_data(irq);
349 void __iomem *mapbase = sachip->base + SA1111_INTC;
290 unsigned long ie1; 350 unsigned long ie1;
291 351
292 ie1 = sa1111_readl(mapbase + SA1111_INTEN1); 352 ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
@@ -296,7 +356,8 @@ static void sa1111_mask_highirq(unsigned int irq)
296 356
297static void sa1111_unmask_highirq(unsigned int irq) 357static void sa1111_unmask_highirq(unsigned int irq)
298{ 358{
299 void __iomem *mapbase = get_irq_chip_data(irq); 359 struct sa1111 *sachip = get_irq_chip_data(irq);
360 void __iomem *mapbase = sachip->base + SA1111_INTC;
300 unsigned long ie1; 361 unsigned long ie1;
301 362
302 ie1 = sa1111_readl(mapbase + SA1111_INTEN1); 363 ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
@@ -313,8 +374,9 @@ static void sa1111_unmask_highirq(unsigned int irq)
313 */ 374 */
314static int sa1111_retrigger_highirq(unsigned int irq) 375static int sa1111_retrigger_highirq(unsigned int irq)
315{ 376{
377 struct sa1111 *sachip = get_irq_chip_data(irq);
378 void __iomem *mapbase = sachip->base + SA1111_INTC;
316 unsigned int mask = SA1111_IRQMASK_HI(irq); 379 unsigned int mask = SA1111_IRQMASK_HI(irq);
317 void __iomem *mapbase = get_irq_chip_data(irq);
318 unsigned long ip1; 380 unsigned long ip1;
319 int i; 381 int i;
320 382
@@ -334,8 +396,9 @@ static int sa1111_retrigger_highirq(unsigned int irq)
334 396
335static int sa1111_type_highirq(unsigned int irq, unsigned int flags) 397static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
336{ 398{
399 struct sa1111 *sachip = get_irq_chip_data(irq);
400 void __iomem *mapbase = sachip->base + SA1111_INTC;
337 unsigned int mask = SA1111_IRQMASK_HI(irq); 401 unsigned int mask = SA1111_IRQMASK_HI(irq);
338 void __iomem *mapbase = get_irq_chip_data(irq);
339 unsigned long ip1; 402 unsigned long ip1;
340 403
341 if (flags == IRQ_TYPE_PROBE) 404 if (flags == IRQ_TYPE_PROBE)
@@ -357,8 +420,9 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
357 420
358static int sa1111_wake_highirq(unsigned int irq, unsigned int on) 421static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
359{ 422{
423 struct sa1111 *sachip = get_irq_chip_data(irq);
424 void __iomem *mapbase = sachip->base + SA1111_INTC;
360 unsigned int mask = SA1111_IRQMASK_HI(irq); 425 unsigned int mask = SA1111_IRQMASK_HI(irq);
361 void __iomem *mapbase = get_irq_chip_data(irq);
362 unsigned long we1; 426 unsigned long we1;
363 427
364 we1 = sa1111_readl(mapbase + SA1111_WAKEEN1); 428 we1 = sa1111_readl(mapbase + SA1111_WAKEEN1);
@@ -412,14 +476,14 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
412 476
413 for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { 477 for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
414 set_irq_chip(irq, &sa1111_low_chip); 478 set_irq_chip(irq, &sa1111_low_chip);
415 set_irq_chip_data(irq, irqbase); 479 set_irq_chip_data(irq, sachip);
416 set_irq_handler(irq, handle_edge_irq); 480 set_irq_handler(irq, handle_edge_irq);
417 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 481 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
418 } 482 }
419 483
420 for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { 484 for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
421 set_irq_chip(irq, &sa1111_high_chip); 485 set_irq_chip(irq, &sa1111_high_chip);
422 set_irq_chip_data(irq, irqbase); 486 set_irq_chip_data(irq, sachip);
423 set_irq_handler(irq, handle_edge_irq); 487 set_irq_handler(irq, handle_edge_irq);
424 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 488 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
425 } 489 }
@@ -428,7 +492,7 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
428 * Register SA1111 interrupt 492 * Register SA1111 interrupt
429 */ 493 */
430 set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING); 494 set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
431 set_irq_data(sachip->irq, irqbase); 495 set_irq_data(sachip->irq, sachip);
432 set_irq_chained_handler(sachip->irq, sa1111_irq_handler); 496 set_irq_chained_handler(sachip->irq, sa1111_irq_handler);
433} 497}
434 498