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