Fix up powernow-k8 compile. (Missing definitions).
[pandora-kernel.git] / arch / arm / mach-s3c2410 / irq.c
1 /* linux/arch/arm/mach-s3c2410/irq.c
2  *
3  * Copyright (c) 2003,2004 Simtec Electronics
4  *      Ben Dooks <ben@simtec.co.uk>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Changelog:
21  *
22  *   22-Jul-2004  Ben Dooks <ben@simtec.co.uk>
23  *                Fixed compile warnings
24  *
25  *   22-Jul-2004  Roc Wu <cooloney@yahoo.com.cn>
26  *                Fixed s3c_extirq_type
27  *
28  *   21-Jul-2004  Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
29  *                Addition of ADC/TC demux
30  *
31  *   04-Oct-2004  Klaus Fetscher <k.fetscher@fetron.de>
32  *                Fix for set_irq_type() on low EINT numbers
33  *
34  *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
35  *                Tidy up KF's patch and sort out new release
36  *
37  *   05-Oct-2004  Ben Dooks <ben@simtec.co.uk>
38  *                Add support for power management controls
39  *
40  *   04-Nov-2004  Ben Dooks
41  *                Fix standard IRQ wake for EINT0..4 and RTC
42  *
43  *   22-Feb-2005  Ben Dooks
44  *                Fixed edge-triggering on ADC IRQ
45  *
46  *   28-Jun-2005  Ben Dooks
47  *                Mark IRQ_LCD valid
48 */
49
50 #include <linux/init.h>
51 #include <linux/module.h>
52 #include <linux/interrupt.h>
53 #include <linux/ioport.h>
54 #include <linux/ptrace.h>
55 #include <linux/sysdev.h>
56
57 #include <asm/hardware.h>
58 #include <asm/irq.h>
59 #include <asm/io.h>
60
61 #include <asm/mach/irq.h>
62
63 #include <asm/arch/regs-irq.h>
64 #include <asm/arch/regs-gpio.h>
65
66 #include "cpu.h"
67 #include "pm.h"
68
69 #define irqdbf(x...)
70 #define irqdbf2(x...)
71
72 #define EXTINT_OFF (IRQ_EINT4 - 4)
73
74 /* wakeup irq control */
75
76 #ifdef CONFIG_PM
77
78 /* state for IRQs over sleep */
79
80 /* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
81  *
82  * set bit to 1 in allow bitfield to enable the wakeup settings on it
83 */
84
85 unsigned long s3c_irqwake_intallow      = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
86 unsigned long s3c_irqwake_intmask       = 0xffffffffL;
87 unsigned long s3c_irqwake_eintallow     = 0x0000fff0L;
88 unsigned long s3c_irqwake_eintmask      = 0xffffffffL;
89
90 static int
91 s3c_irq_wake(unsigned int irqno, unsigned int state)
92 {
93         unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
94
95         if (!(s3c_irqwake_intallow & irqbit))
96                 return -ENOENT;
97
98         printk(KERN_INFO "wake %s for irq %d\n",
99                state ? "enabled" : "disabled", irqno);
100
101         if (!state)
102                 s3c_irqwake_intmask |= irqbit;
103         else
104                 s3c_irqwake_intmask &= ~irqbit;
105
106         return 0;
107 }
108
109 static int
110 s3c_irqext_wake(unsigned int irqno, unsigned int state)
111 {
112         unsigned long bit = 1L << (irqno - EXTINT_OFF);
113
114         if (!(s3c_irqwake_eintallow & bit))
115                 return -ENOENT;
116
117         printk(KERN_INFO "wake %s for irq %d\n",
118                state ? "enabled" : "disabled", irqno);
119
120         if (!state)
121                 s3c_irqwake_eintmask |= bit;
122         else
123                 s3c_irqwake_eintmask &= ~bit;
124
125         return 0;
126 }
127
128 #else
129 #define s3c_irqext_wake NULL
130 #define s3c_irq_wake NULL
131 #endif
132
133
134 static void
135 s3c_irq_mask(unsigned int irqno)
136 {
137         unsigned long mask;
138
139         irqno -= IRQ_EINT0;
140
141         mask = __raw_readl(S3C2410_INTMSK);
142         mask |= 1UL << irqno;
143         __raw_writel(mask, S3C2410_INTMSK);
144 }
145
146 static inline void
147 s3c_irq_ack(unsigned int irqno)
148 {
149         unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
150
151         __raw_writel(bitval, S3C2410_SRCPND);
152         __raw_writel(bitval, S3C2410_INTPND);
153 }
154
155 static inline void
156 s3c_irq_maskack(unsigned int irqno)
157 {
158         unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
159         unsigned long mask;
160
161         mask = __raw_readl(S3C2410_INTMSK);
162         __raw_writel(mask|bitval, S3C2410_INTMSK);
163
164         __raw_writel(bitval, S3C2410_SRCPND);
165         __raw_writel(bitval, S3C2410_INTPND);
166 }
167
168
169 static void
170 s3c_irq_unmask(unsigned int irqno)
171 {
172         unsigned long mask;
173
174         if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
175                 irqdbf2("s3c_irq_unmask %d\n", irqno);
176
177         irqno -= IRQ_EINT0;
178
179         mask = __raw_readl(S3C2410_INTMSK);
180         mask &= ~(1UL << irqno);
181         __raw_writel(mask, S3C2410_INTMSK);
182 }
183
184 static struct irqchip s3c_irq_level_chip = {
185         .ack       = s3c_irq_maskack,
186         .mask      = s3c_irq_mask,
187         .unmask    = s3c_irq_unmask,
188         .wake      = s3c_irq_wake
189 };
190
191 static struct irqchip s3c_irq_chip = {
192         .ack       = s3c_irq_ack,
193         .mask      = s3c_irq_mask,
194         .unmask    = s3c_irq_unmask,
195         .wake      = s3c_irq_wake
196 };
197
198 /* S3C2410_EINTMASK
199  * S3C2410_EINTPEND
200  */
201
202 static void
203 s3c_irqext_mask(unsigned int irqno)
204 {
205         unsigned long mask;
206
207         irqno -= EXTINT_OFF;
208
209         mask = __raw_readl(S3C2410_EINTMASK);
210         mask |= ( 1UL << irqno);
211         __raw_writel(mask, S3C2410_EINTMASK);
212
213         if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) {
214                 /* check to see if all need masking */
215
216                 if ((mask & (0xf << 4)) == (0xf << 4)) {
217                         /* all masked, mask the parent */
218                         s3c_irq_mask(IRQ_EINT4t7);
219                 }
220         } else {
221                 /* todo: the same check as above for the rest of the irq regs...*/
222
223         }
224 }
225
226 static void
227 s3c_irqext_ack(unsigned int irqno)
228 {
229         unsigned long req;
230         unsigned long bit;
231         unsigned long mask;
232
233         bit = 1UL << (irqno - EXTINT_OFF);
234
235
236         mask = __raw_readl(S3C2410_EINTMASK);
237
238         __raw_writel(bit, S3C2410_EINTPEND);
239
240         req = __raw_readl(S3C2410_EINTPEND);
241         req &= ~mask;
242
243         /* not sure if we should be acking the parent irq... */
244
245         if (irqno <= IRQ_EINT7 ) {
246                 if ((req & 0xf0) == 0)
247                         s3c_irq_ack(IRQ_EINT4t7);
248         } else {
249                 if ((req >> 8) == 0)
250                         s3c_irq_ack(IRQ_EINT8t23);
251         }
252 }
253
254 static void
255 s3c_irqext_unmask(unsigned int irqno)
256 {
257         unsigned long mask;
258
259         irqno -= EXTINT_OFF;
260
261         mask = __raw_readl(S3C2410_EINTMASK);
262         mask &= ~( 1UL << irqno);
263         __raw_writel(mask, S3C2410_EINTMASK);
264
265         s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23);
266 }
267
268 static int
269 s3c_irqext_type(unsigned int irq, unsigned int type)
270 {
271         void __iomem *extint_reg;
272         void __iomem *gpcon_reg;
273         unsigned long gpcon_offset, extint_offset;
274         unsigned long newvalue = 0, value;
275
276         if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
277         {
278                 gpcon_reg = S3C2410_GPFCON;
279                 extint_reg = S3C2410_EXTINT0;
280                 gpcon_offset = (irq - IRQ_EINT0) * 2;
281                 extint_offset = (irq - IRQ_EINT0) * 4;
282         }
283         else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
284         {
285                 gpcon_reg = S3C2410_GPFCON;
286                 extint_reg = S3C2410_EXTINT0;
287                 gpcon_offset = (irq - (EXTINT_OFF)) * 2;
288                 extint_offset = (irq - (EXTINT_OFF)) * 4;
289         }
290         else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
291         {
292                 gpcon_reg = S3C2410_GPGCON;
293                 extint_reg = S3C2410_EXTINT1;
294                 gpcon_offset = (irq - IRQ_EINT8) * 2;
295                 extint_offset = (irq - IRQ_EINT8) * 4;
296         }
297         else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
298         {
299                 gpcon_reg = S3C2410_GPGCON;
300                 extint_reg = S3C2410_EXTINT2;
301                 gpcon_offset = (irq - IRQ_EINT8) * 2;
302                 extint_offset = (irq - IRQ_EINT16) * 4;
303         } else
304                 return -1;
305
306         /* Set the GPIO to external interrupt mode */
307         value = __raw_readl(gpcon_reg);
308         value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
309         __raw_writel(value, gpcon_reg);
310
311         /* Set the external interrupt to pointed trigger type */
312         switch (type)
313         {
314                 case IRQT_NOEDGE:
315                         printk(KERN_WARNING "No edge setting!\n");
316                         break;
317
318                 case IRQT_RISING:
319                         newvalue = S3C2410_EXTINT_RISEEDGE;
320                         break;
321
322                 case IRQT_FALLING:
323                         newvalue = S3C2410_EXTINT_FALLEDGE;
324                         break;
325
326                 case IRQT_BOTHEDGE:
327                         newvalue = S3C2410_EXTINT_BOTHEDGE;
328                         break;
329
330                 case IRQT_LOW:
331                         newvalue = S3C2410_EXTINT_LOWLEV;
332                         break;
333
334                 case IRQT_HIGH:
335                         newvalue = S3C2410_EXTINT_HILEV;
336                         break;
337
338                 default:
339                         printk(KERN_ERR "No such irq type %d", type);
340                         return -1;
341         }
342
343         value = __raw_readl(extint_reg);
344         value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
345         __raw_writel(value, extint_reg);
346
347         return 0;
348 }
349
350 static struct irqchip s3c_irqext_chip = {
351         .mask       = s3c_irqext_mask,
352         .unmask     = s3c_irqext_unmask,
353         .ack        = s3c_irqext_ack,
354         .type       = s3c_irqext_type,
355         .wake       = s3c_irqext_wake
356 };
357
358 static struct irqchip s3c_irq_eint0t4 = {
359         .ack       = s3c_irq_ack,
360         .mask      = s3c_irq_mask,
361         .unmask    = s3c_irq_unmask,
362         .wake      = s3c_irq_wake,
363         .type      = s3c_irqext_type,
364 };
365
366 /* mask values for the parent registers for each of the interrupt types */
367
368 #define INTMSK_UART0     (1UL << (IRQ_UART0 - IRQ_EINT0))
369 #define INTMSK_UART1     (1UL << (IRQ_UART1 - IRQ_EINT0))
370 #define INTMSK_UART2     (1UL << (IRQ_UART2 - IRQ_EINT0))
371 #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
372
373 static inline void
374 s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
375                 int subcheck)
376 {
377         unsigned long mask;
378         unsigned long submask;
379
380         submask = __raw_readl(S3C2410_INTSUBMSK);
381         mask = __raw_readl(S3C2410_INTMSK);
382
383         submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
384
385         /* check to see if we need to mask the parent IRQ */
386
387         if ((submask  & subcheck) == subcheck) {
388                 __raw_writel(mask | parentbit, S3C2410_INTMSK);
389         }
390
391         /* write back masks */
392         __raw_writel(submask, S3C2410_INTSUBMSK);
393
394 }
395
396 static inline void
397 s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
398 {
399         unsigned long mask;
400         unsigned long submask;
401
402         submask = __raw_readl(S3C2410_INTSUBMSK);
403         mask = __raw_readl(S3C2410_INTMSK);
404
405         submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
406         mask &= ~parentbit;
407
408         /* write back masks */
409         __raw_writel(submask, S3C2410_INTSUBMSK);
410         __raw_writel(mask, S3C2410_INTMSK);
411 }
412
413
414 static inline void
415 s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group)
416 {
417         unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
418
419         s3c_irqsub_mask(irqno, parentmask, group);
420
421         __raw_writel(bit, S3C2410_SUBSRCPND);
422
423         /* only ack parent if we've got all the irqs (seems we must
424          * ack, all and hope that the irq system retriggers ok when
425          * the interrupt goes off again)
426          */
427
428         if (1) {
429                 __raw_writel(parentmask, S3C2410_SRCPND);
430                 __raw_writel(parentmask, S3C2410_INTPND);
431         }
432 }
433
434 static inline void
435 s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
436 {
437         unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
438
439         __raw_writel(bit, S3C2410_SUBSRCPND);
440
441         /* only ack parent if we've got all the irqs (seems we must
442          * ack, all and hope that the irq system retriggers ok when
443          * the interrupt goes off again)
444          */
445
446         if (1) {
447                 __raw_writel(parentmask, S3C2410_SRCPND);
448                 __raw_writel(parentmask, S3C2410_INTPND);
449         }
450 }
451
452 /* UART0 */
453
454 static void
455 s3c_irq_uart0_mask(unsigned int irqno)
456 {
457         s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
458 }
459
460 static void
461 s3c_irq_uart0_unmask(unsigned int irqno)
462 {
463         s3c_irqsub_unmask(irqno, INTMSK_UART0);
464 }
465
466 static void
467 s3c_irq_uart0_ack(unsigned int irqno)
468 {
469         s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
470 }
471
472 static struct irqchip s3c_irq_uart0 = {
473         .mask       = s3c_irq_uart0_mask,
474         .unmask     = s3c_irq_uart0_unmask,
475         .ack        = s3c_irq_uart0_ack,
476 };
477
478 /* UART1 */
479
480 static void
481 s3c_irq_uart1_mask(unsigned int irqno)
482 {
483         s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
484 }
485
486 static void
487 s3c_irq_uart1_unmask(unsigned int irqno)
488 {
489         s3c_irqsub_unmask(irqno, INTMSK_UART1);
490 }
491
492 static void
493 s3c_irq_uart1_ack(unsigned int irqno)
494 {
495         s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
496 }
497
498 static struct irqchip s3c_irq_uart1 = {
499         .mask       = s3c_irq_uart1_mask,
500         .unmask     = s3c_irq_uart1_unmask,
501         .ack        = s3c_irq_uart1_ack,
502 };
503
504 /* UART2 */
505
506 static void
507 s3c_irq_uart2_mask(unsigned int irqno)
508 {
509         s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
510 }
511
512 static void
513 s3c_irq_uart2_unmask(unsigned int irqno)
514 {
515         s3c_irqsub_unmask(irqno, INTMSK_UART2);
516 }
517
518 static void
519 s3c_irq_uart2_ack(unsigned int irqno)
520 {
521         s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
522 }
523
524 static struct irqchip s3c_irq_uart2 = {
525         .mask       = s3c_irq_uart2_mask,
526         .unmask     = s3c_irq_uart2_unmask,
527         .ack        = s3c_irq_uart2_ack,
528 };
529
530 /* ADC and Touchscreen */
531
532 static void
533 s3c_irq_adc_mask(unsigned int irqno)
534 {
535         s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
536 }
537
538 static void
539 s3c_irq_adc_unmask(unsigned int irqno)
540 {
541         s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
542 }
543
544 static void
545 s3c_irq_adc_ack(unsigned int irqno)
546 {
547         s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
548 }
549
550 static struct irqchip s3c_irq_adc = {
551         .mask       = s3c_irq_adc_mask,
552         .unmask     = s3c_irq_adc_unmask,
553         .ack        = s3c_irq_adc_ack,
554 };
555
556 /* irq demux for adc */
557 static void s3c_irq_demux_adc(unsigned int irq,
558                               struct irqdesc *desc,
559                               struct pt_regs *regs)
560 {
561         unsigned int subsrc, submsk;
562         unsigned int offset = 9;
563         struct irqdesc *mydesc;
564
565         /* read the current pending interrupts, and the mask
566          * for what it is available */
567
568         subsrc = __raw_readl(S3C2410_SUBSRCPND);
569         submsk = __raw_readl(S3C2410_INTSUBMSK);
570
571         subsrc &= ~submsk;
572         subsrc >>= offset;
573         subsrc &= 3;
574
575         if (subsrc != 0) {
576                 if (subsrc & 1) {
577                         mydesc = irq_desc + IRQ_TC;
578                         mydesc->handle( IRQ_TC, mydesc, regs);
579                 }
580                 if (subsrc & 2) {
581                         mydesc = irq_desc + IRQ_ADC;
582                         mydesc->handle(IRQ_ADC, mydesc, regs);
583                 }
584         }
585 }
586
587 static void s3c_irq_demux_uart(unsigned int start,
588                                struct pt_regs *regs)
589 {
590         unsigned int subsrc, submsk;
591         unsigned int offset = start - IRQ_S3CUART_RX0;
592         struct irqdesc *desc;
593
594         /* read the current pending interrupts, and the mask
595          * for what it is available */
596
597         subsrc = __raw_readl(S3C2410_SUBSRCPND);
598         submsk = __raw_readl(S3C2410_INTSUBMSK);
599
600         irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
601                 start, offset, subsrc, submsk);
602
603         subsrc &= ~submsk;
604         subsrc >>= offset;
605         subsrc &= 7;
606
607         if (subsrc != 0) {
608                 desc = irq_desc + start;
609
610                 if (subsrc & 1)
611                         desc->handle(start, desc, regs);
612
613                 desc++;
614
615                 if (subsrc & 2)
616                         desc->handle(start+1, desc, regs);
617
618                 desc++;
619
620                 if (subsrc & 4)
621                         desc->handle(start+2, desc, regs);
622         }
623 }
624
625 /* uart demux entry points */
626
627 static void
628 s3c_irq_demux_uart0(unsigned int irq,
629                     struct irqdesc *desc,
630                     struct pt_regs *regs)
631 {
632         irq = irq;
633         s3c_irq_demux_uart(IRQ_S3CUART_RX0, regs);
634 }
635
636 static void
637 s3c_irq_demux_uart1(unsigned int irq,
638                     struct irqdesc *desc,
639                     struct pt_regs *regs)
640 {
641         irq = irq;
642         s3c_irq_demux_uart(IRQ_S3CUART_RX1, regs);
643 }
644
645 static void
646 s3c_irq_demux_uart2(unsigned int irq,
647                     struct irqdesc *desc,
648                     struct pt_regs *regs)
649 {
650         irq = irq;
651         s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs);
652 }
653
654
655 /* s3c24xx_init_irq
656  *
657  * Initialise S3C2410 IRQ system
658 */
659
660 void __init s3c24xx_init_irq(void)
661 {
662         unsigned long pend;
663         unsigned long last;
664         int irqno;
665         int i;
666
667         irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
668
669         /* first, clear all interrupts pending... */
670
671         last = 0;
672         for (i = 0; i < 4; i++) {
673                 pend = __raw_readl(S3C2410_EINTPEND);
674
675                 if (pend == 0 || pend == last)
676                         break;
677
678                 __raw_writel(pend, S3C2410_EINTPEND);
679                 printk("irq: clearing pending ext status %08x\n", (int)pend);
680                 last = pend;
681         }
682
683         last = 0;
684         for (i = 0; i < 4; i++) {
685                 pend = __raw_readl(S3C2410_INTPND);
686
687                 if (pend == 0 || pend == last)
688                         break;
689
690                 __raw_writel(pend, S3C2410_SRCPND);
691                 __raw_writel(pend, S3C2410_INTPND);
692                 printk("irq: clearing pending status %08x\n", (int)pend);
693                 last = pend;
694         }
695
696         last = 0;
697         for (i = 0; i < 4; i++) {
698                 pend = __raw_readl(S3C2410_SUBSRCPND);
699
700                 if (pend == 0 || pend == last)
701                         break;
702
703                 printk("irq: clearing subpending status %08x\n", (int)pend);
704                 __raw_writel(pend, S3C2410_SUBSRCPND);
705                 last = pend;
706         }
707
708         /* register the main interrupts */
709
710         irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
711
712         for (irqno = IRQ_BATT_FLT; irqno <= IRQ_ADCPARENT; irqno++) {
713                 /* set all the s3c2410 internal irqs */
714
715                 switch (irqno) {
716                         /* deal with the special IRQs (cascaded) */
717
718                 case IRQ_UART0:
719                 case IRQ_UART1:
720                 case IRQ_UART2:
721                 case IRQ_ADCPARENT:
722                         set_irq_chip(irqno, &s3c_irq_level_chip);
723                         set_irq_handler(irqno, do_level_IRQ);
724                         break;
725
726                 case IRQ_RESERVED6:
727                 case IRQ_RESERVED24:
728                         /* no IRQ here */
729                         break;
730
731                 default:
732                         //irqdbf("registering irq %d (s3c irq)\n", irqno);
733                         set_irq_chip(irqno, &s3c_irq_chip);
734                         set_irq_handler(irqno, do_edge_IRQ);
735                         set_irq_flags(irqno, IRQF_VALID);
736                 }
737         }
738
739         /* setup the cascade irq handlers */
740
741         set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
742         set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
743         set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
744         set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
745
746
747         /* external interrupts */
748
749         for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
750                 irqdbf("registering irq %d (ext int)\n", irqno);
751                 set_irq_chip(irqno, &s3c_irq_eint0t4);
752                 set_irq_handler(irqno, do_edge_IRQ);
753                 set_irq_flags(irqno, IRQF_VALID);
754         }
755
756         for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
757                 irqdbf("registering irq %d (extended s3c irq)\n", irqno);
758                 set_irq_chip(irqno, &s3c_irqext_chip);
759                 set_irq_handler(irqno, do_edge_IRQ);
760                 set_irq_flags(irqno, IRQF_VALID);
761         }
762
763         /* register the uart interrupts */
764
765         irqdbf("s3c2410: registering external interrupts\n");
766
767         for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
768                 irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
769                 set_irq_chip(irqno, &s3c_irq_uart0);
770                 set_irq_handler(irqno, do_level_IRQ);
771                 set_irq_flags(irqno, IRQF_VALID);
772         }
773
774         for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
775                 irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
776                 set_irq_chip(irqno, &s3c_irq_uart1);
777                 set_irq_handler(irqno, do_level_IRQ);
778                 set_irq_flags(irqno, IRQF_VALID);
779         }
780
781         for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
782                 irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
783                 set_irq_chip(irqno, &s3c_irq_uart2);
784                 set_irq_handler(irqno, do_level_IRQ);
785                 set_irq_flags(irqno, IRQF_VALID);
786         }
787
788         for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
789                 irqdbf("registering irq %d (s3c adc irq)\n", irqno);
790                 set_irq_chip(irqno, &s3c_irq_adc);
791                 set_irq_handler(irqno, do_edge_IRQ);
792                 set_irq_flags(irqno, IRQF_VALID);
793         }
794
795         irqdbf("s3c2410: registered interrupt handlers\n");
796 }
797
798 /* s3c2440 irq code
799 */
800
801 #ifdef CONFIG_CPU_S3C2440
802
803 /* WDT/AC97 */
804
805 static void s3c_irq_demux_wdtac97(unsigned int irq,
806                                   struct irqdesc *desc,
807                                   struct pt_regs *regs)
808 {
809         unsigned int subsrc, submsk;
810         struct irqdesc *mydesc;
811
812         /* read the current pending interrupts, and the mask
813          * for what it is available */
814
815         subsrc = __raw_readl(S3C2410_SUBSRCPND);
816         submsk = __raw_readl(S3C2410_INTSUBMSK);
817
818         subsrc &= ~submsk;
819         subsrc >>= 13;
820         subsrc &= 3;
821
822         if (subsrc != 0) {
823                 if (subsrc & 1) {
824                         mydesc = irq_desc + IRQ_S3C2440_WDT;
825                         mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
826                 }
827                 if (subsrc & 2) {
828                         mydesc = irq_desc + IRQ_S3C2440_AC97;
829                         mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
830                 }
831         }
832 }
833
834
835 #define INTMSK_WDT       (1UL << (IRQ_WDT - IRQ_EINT0))
836
837 static void
838 s3c_irq_wdtac97_mask(unsigned int irqno)
839 {
840         s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13);
841 }
842
843 static void
844 s3c_irq_wdtac97_unmask(unsigned int irqno)
845 {
846         s3c_irqsub_unmask(irqno, INTMSK_WDT);
847 }
848
849 static void
850 s3c_irq_wdtac97_ack(unsigned int irqno)
851 {
852         s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13);
853 }
854
855 static struct irqchip s3c_irq_wdtac97 = {
856         .mask       = s3c_irq_wdtac97_mask,
857         .unmask     = s3c_irq_wdtac97_unmask,
858         .ack        = s3c_irq_wdtac97_ack,
859 };
860
861 /* camera irq */
862
863 static void s3c_irq_demux_cam(unsigned int irq,
864                               struct irqdesc *desc,
865                               struct pt_regs *regs)
866 {
867         unsigned int subsrc, submsk;
868         struct irqdesc *mydesc;
869
870         /* read the current pending interrupts, and the mask
871          * for what it is available */
872
873         subsrc = __raw_readl(S3C2410_SUBSRCPND);
874         submsk = __raw_readl(S3C2410_INTSUBMSK);
875
876         subsrc &= ~submsk;
877         subsrc >>= 11;
878         subsrc &= 3;
879
880         if (subsrc != 0) {
881                 if (subsrc & 1) {
882                         mydesc = irq_desc + IRQ_S3C2440_CAM_C;
883                         mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
884                 }
885                 if (subsrc & 2) {
886                         mydesc = irq_desc + IRQ_S3C2440_CAM_P;
887                         mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
888                 }
889         }
890 }
891
892 #define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
893
894 static void
895 s3c_irq_cam_mask(unsigned int irqno)
896 {
897         s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
898 }
899
900 static void
901 s3c_irq_cam_unmask(unsigned int irqno)
902 {
903         s3c_irqsub_unmask(irqno, INTMSK_CAM);
904 }
905
906 static void
907 s3c_irq_cam_ack(unsigned int irqno)
908 {
909         s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
910 }
911
912 static struct irqchip s3c_irq_cam = {
913         .mask       = s3c_irq_cam_mask,
914         .unmask     = s3c_irq_cam_unmask,
915         .ack        = s3c_irq_cam_ack,
916 };
917
918 static int s3c2440_irq_add(struct sys_device *sysdev)
919 {
920         unsigned int irqno;
921
922         printk("S3C2440: IRQ Support\n");
923
924         set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
925         set_irq_handler(IRQ_NFCON, do_level_IRQ);
926         set_irq_flags(IRQ_NFCON, IRQF_VALID);
927
928         /* add new chained handler for wdt, ac7 */
929
930         set_irq_chip(IRQ_WDT, &s3c_irq_level_chip);
931         set_irq_handler(IRQ_WDT, do_level_IRQ);
932         set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
933
934         for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
935                 set_irq_chip(irqno, &s3c_irq_wdtac97);
936                 set_irq_handler(irqno, do_level_IRQ);
937                 set_irq_flags(irqno, IRQF_VALID);
938         }
939
940         /* add chained handler for camera */
941
942         set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
943         set_irq_handler(IRQ_CAM, do_level_IRQ);
944         set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
945
946         for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
947                 set_irq_chip(irqno, &s3c_irq_cam);
948                 set_irq_handler(irqno, do_level_IRQ);
949                 set_irq_flags(irqno, IRQF_VALID);
950         }
951
952         return 0;
953 }
954
955 static struct sysdev_driver s3c2440_irq_driver = {
956         .add    = s3c2440_irq_add,
957 };
958
959 static int s3c24xx_irq_driver(void)
960 {
961         return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
962 }
963
964 arch_initcall(s3c24xx_irq_driver);
965
966 #endif /* CONFIG_CPU_S3C2440 */
967