Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / arm / mach-s3c2410 / irq.c
blobb668c48f43990f3648f248f8c17399f884568b4f
1 /* linux/arch/arm/mach-s3c2410/irq.c
3 * Copyright (c) 2003,2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
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.
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.
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
20 * Changelog:
22 * 22-Jul-2004 Ben Dooks <ben@simtec.co.uk>
23 * Fixed compile warnings
25 * 22-Jul-2004 Roc Wu <cooloney@yahoo.com.cn>
26 * Fixed s3c_extirq_type
28 * 21-Jul-2004 Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
29 * Addition of ADC/TC demux
31 * 04-Oct-2004 Klaus Fetscher <k.fetscher@fetron.de>
32 * Fix for set_irq_type() on low EINT numbers
34 * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
35 * Tidy up KF's patch and sort out new release
37 * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
38 * Add support for power management controls
40 * 04-Nov-2004 Ben Dooks
41 * Fix standard IRQ wake for EINT0..4 and RTC
43 * 22-Feb-2004 Ben Dooks
44 * Fixed edge-triggering on ADC IRQ
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>
54 #include <asm/hardware.h>
55 #include <asm/irq.h>
56 #include <asm/io.h>
58 #include <asm/mach/irq.h>
60 #include <asm/arch/regs-irq.h>
61 #include <asm/arch/regs-gpio.h>
63 #include "cpu.h"
64 #include "pm.h"
66 #define irqdbf(x...)
67 #define irqdbf2(x...)
69 #define EXTINT_OFF (IRQ_EINT4 - 4)
71 /* wakeup irq control */
73 #ifdef CONFIG_PM
75 /* state for IRQs over sleep */
77 /* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
79 * set bit to 1 in allow bitfield to enable the wakeup settings on it
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;
87 static int
88 s3c_irq_wake(unsigned int irqno, unsigned int state)
90 unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
92 if (!(s3c_irqwake_intallow & irqbit))
93 return -ENOENT;
95 printk(KERN_INFO "wake %s for irq %d\n",
96 state ? "enabled" : "disabled", irqno);
98 if (!state)
99 s3c_irqwake_intmask |= irqbit;
100 else
101 s3c_irqwake_intmask &= ~irqbit;
103 return 0;
106 static int
107 s3c_irqext_wake(unsigned int irqno, unsigned int state)
109 unsigned long bit = 1L << (irqno - EXTINT_OFF);
111 if (!(s3c_irqwake_eintallow & bit))
112 return -ENOENT;
114 printk(KERN_INFO "wake %s for irq %d\n",
115 state ? "enabled" : "disabled", irqno);
117 if (!state)
118 s3c_irqwake_eintmask |= bit;
119 else
120 s3c_irqwake_eintmask &= ~bit;
122 return 0;
125 #else
126 #define s3c_irqext_wake NULL
127 #define s3c_irq_wake NULL
128 #endif
131 static void
132 s3c_irq_mask(unsigned int irqno)
134 unsigned long mask;
136 irqno -= IRQ_EINT0;
138 mask = __raw_readl(S3C2410_INTMSK);
139 mask |= 1UL << irqno;
140 __raw_writel(mask, S3C2410_INTMSK);
143 static inline void
144 s3c_irq_ack(unsigned int irqno)
146 unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
148 __raw_writel(bitval, S3C2410_SRCPND);
149 __raw_writel(bitval, S3C2410_INTPND);
152 static inline void
153 s3c_irq_maskack(unsigned int irqno)
155 unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
156 unsigned long mask;
158 mask = __raw_readl(S3C2410_INTMSK);
159 __raw_writel(mask|bitval, S3C2410_INTMSK);
161 __raw_writel(bitval, S3C2410_SRCPND);
162 __raw_writel(bitval, S3C2410_INTPND);
166 static void
167 s3c_irq_unmask(unsigned int irqno)
169 unsigned long mask;
171 if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
172 irqdbf2("s3c_irq_unmask %d\n", irqno);
174 irqno -= IRQ_EINT0;
176 mask = __raw_readl(S3C2410_INTMSK);
177 mask &= ~(1UL << irqno);
178 __raw_writel(mask, S3C2410_INTMSK);
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
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
195 /* S3C2410_EINTMASK
196 * S3C2410_EINTPEND
199 static void
200 s3c_irqext_mask(unsigned int irqno)
202 unsigned long mask;
204 irqno -= EXTINT_OFF;
206 mask = __raw_readl(S3C2410_EINTMASK);
207 mask |= ( 1UL << irqno);
208 __raw_writel(mask, S3C2410_EINTMASK);
210 if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) {
211 /* check to see if all need masking */
213 if ((mask & (0xf << 4)) == (0xf << 4)) {
214 /* all masked, mask the parent */
215 s3c_irq_mask(IRQ_EINT4t7);
217 } else {
218 /* todo: the same check as above for the rest of the irq regs...*/
223 static void
224 s3c_irqext_ack(unsigned int irqno)
226 unsigned long req;
227 unsigned long bit;
228 unsigned long mask;
230 bit = 1UL << (irqno - EXTINT_OFF);
233 mask = __raw_readl(S3C2410_EINTMASK);
235 __raw_writel(bit, S3C2410_EINTPEND);
237 req = __raw_readl(S3C2410_EINTPEND);
238 req &= ~mask;
240 /* not sure if we should be acking the parent irq... */
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);
251 static void
252 s3c_irqext_unmask(unsigned int irqno)
254 unsigned long mask;
256 irqno -= EXTINT_OFF;
258 mask = __raw_readl(S3C2410_EINTMASK);
259 mask &= ~( 1UL << irqno);
260 __raw_writel(mask, S3C2410_EINTMASK);
262 s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23);
265 static int
266 s3c_irqext_type(unsigned int irq, unsigned int type)
268 void __iomem *extint_reg;
269 void __iomem *gpcon_reg;
270 unsigned long gpcon_offset, extint_offset;
271 unsigned long newvalue = 0, value;
273 if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
275 gpcon_reg = S3C2410_GPFCON;
276 extint_reg = S3C2410_EXTINT0;
277 gpcon_offset = (irq - IRQ_EINT0) * 2;
278 extint_offset = (irq - IRQ_EINT0) * 4;
280 else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
282 gpcon_reg = S3C2410_GPFCON;
283 extint_reg = S3C2410_EXTINT0;
284 gpcon_offset = (irq - (EXTINT_OFF)) * 2;
285 extint_offset = (irq - (EXTINT_OFF)) * 4;
287 else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
289 gpcon_reg = S3C2410_GPGCON;
290 extint_reg = S3C2410_EXTINT1;
291 gpcon_offset = (irq - IRQ_EINT8) * 2;
292 extint_offset = (irq - IRQ_EINT8) * 4;
294 else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
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;
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);
308 /* Set the external interrupt to pointed trigger type */
309 switch (type)
311 case IRQT_NOEDGE:
312 printk(KERN_WARNING "No edge setting!\n");
313 break;
315 case IRQT_RISING:
316 newvalue = S3C2410_EXTINT_RISEEDGE;
317 break;
319 case IRQT_FALLING:
320 newvalue = S3C2410_EXTINT_FALLEDGE;
321 break;
323 case IRQT_BOTHEDGE:
324 newvalue = S3C2410_EXTINT_BOTHEDGE;
325 break;
327 case IRQT_LOW:
328 newvalue = S3C2410_EXTINT_LOWLEV;
329 break;
331 case IRQT_HIGH:
332 newvalue = S3C2410_EXTINT_HILEV;
333 break;
335 default:
336 printk(KERN_ERR "No such irq type %d", type);
337 return -1;
340 value = __raw_readl(extint_reg);
341 value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
342 __raw_writel(value, extint_reg);
344 return 0;
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
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,
363 /* mask values for the parent registers for each of the interrupt types */
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))
371 static inline void
372 s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
373 int subcheck)
375 unsigned long mask;
376 unsigned long submask;
378 submask = __raw_readl(S3C2410_INTSUBMSK);
379 mask = __raw_readl(S3C2410_INTMSK);
381 submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
383 /* check to see if we need to mask the parent IRQ */
385 if ((submask & subcheck) == subcheck) {
386 __raw_writel(mask | parentbit, S3C2410_INTMSK);
389 /* write back masks */
390 __raw_writel(submask, S3C2410_INTSUBMSK);
394 static inline void
395 s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
397 unsigned long mask;
398 unsigned long submask;
400 submask = __raw_readl(S3C2410_INTSUBMSK);
401 mask = __raw_readl(S3C2410_INTMSK);
403 submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
404 mask &= ~parentbit;
406 /* write back masks */
407 __raw_writel(submask, S3C2410_INTSUBMSK);
408 __raw_writel(mask, S3C2410_INTMSK);
412 static inline void
413 s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group)
415 unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
417 s3c_irqsub_mask(irqno, parentmask, group);
419 __raw_writel(bit, S3C2410_SUBSRCPND);
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)
426 if (1) {
427 __raw_writel(parentmask, S3C2410_SRCPND);
428 __raw_writel(parentmask, S3C2410_INTPND);
432 static inline void
433 s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
435 unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
437 __raw_writel(bit, S3C2410_SUBSRCPND);
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)
444 if (1) {
445 __raw_writel(parentmask, S3C2410_SRCPND);
446 __raw_writel(parentmask, S3C2410_INTPND);
450 /* UART0 */
452 static void
453 s3c_irq_uart0_mask(unsigned int irqno)
455 s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
458 static void
459 s3c_irq_uart0_unmask(unsigned int irqno)
461 s3c_irqsub_unmask(irqno, INTMSK_UART0);
464 static void
465 s3c_irq_uart0_ack(unsigned int irqno)
467 s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
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,
476 /* UART1 */
478 static void
479 s3c_irq_uart1_mask(unsigned int irqno)
481 s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
484 static void
485 s3c_irq_uart1_unmask(unsigned int irqno)
487 s3c_irqsub_unmask(irqno, INTMSK_UART1);
490 static void
491 s3c_irq_uart1_ack(unsigned int irqno)
493 s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
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,
502 /* UART2 */
504 static void
505 s3c_irq_uart2_mask(unsigned int irqno)
507 s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
510 static void
511 s3c_irq_uart2_unmask(unsigned int irqno)
513 s3c_irqsub_unmask(irqno, INTMSK_UART2);
516 static void
517 s3c_irq_uart2_ack(unsigned int irqno)
519 s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
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,
528 /* ADC and Touchscreen */
530 static void
531 s3c_irq_adc_mask(unsigned int irqno)
533 s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
536 static void
537 s3c_irq_adc_unmask(unsigned int irqno)
539 s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
542 static void
543 s3c_irq_adc_ack(unsigned int irqno)
545 s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
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,
554 /* irq demux for adc */
555 static void s3c_irq_demux_adc(unsigned int irq,
556 struct irqdesc *desc,
557 struct pt_regs *regs)
559 unsigned int subsrc, submsk;
560 unsigned int offset = 9;
561 struct irqdesc *mydesc;
563 /* read the current pending interrupts, and the mask
564 * for what it is available */
566 subsrc = __raw_readl(S3C2410_SUBSRCPND);
567 submsk = __raw_readl(S3C2410_INTSUBMSK);
569 subsrc &= ~submsk;
570 subsrc >>= offset;
571 subsrc &= 3;
573 if (subsrc != 0) {
574 if (subsrc & 1) {
575 mydesc = irq_desc + IRQ_TC;
576 mydesc->handle( IRQ_TC, mydesc, regs);
578 if (subsrc & 2) {
579 mydesc = irq_desc + IRQ_ADC;
580 mydesc->handle(IRQ_ADC, mydesc, regs);
585 static void s3c_irq_demux_uart(unsigned int start,
586 struct pt_regs *regs)
588 unsigned int subsrc, submsk;
589 unsigned int offset = start - IRQ_S3CUART_RX0;
590 struct irqdesc *desc;
592 /* read the current pending interrupts, and the mask
593 * for what it is available */
595 subsrc = __raw_readl(S3C2410_SUBSRCPND);
596 submsk = __raw_readl(S3C2410_INTSUBMSK);
598 irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
599 start, offset, subsrc, submsk);
601 subsrc &= ~submsk;
602 subsrc >>= offset;
603 subsrc &= 7;
605 if (subsrc != 0) {
606 desc = irq_desc + start;
608 if (subsrc & 1)
609 desc->handle(start, desc, regs);
611 desc++;
613 if (subsrc & 2)
614 desc->handle(start+1, desc, regs);
616 desc++;
618 if (subsrc & 4)
619 desc->handle(start+2, desc, regs);
623 /* uart demux entry points */
625 static void
626 s3c_irq_demux_uart0(unsigned int irq,
627 struct irqdesc *desc,
628 struct pt_regs *regs)
630 irq = irq;
631 s3c_irq_demux_uart(IRQ_S3CUART_RX0, regs);
634 static void
635 s3c_irq_demux_uart1(unsigned int irq,
636 struct irqdesc *desc,
637 struct pt_regs *regs)
639 irq = irq;
640 s3c_irq_demux_uart(IRQ_S3CUART_RX1, regs);
643 static void
644 s3c_irq_demux_uart2(unsigned int irq,
645 struct irqdesc *desc,
646 struct pt_regs *regs)
648 irq = irq;
649 s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs);
653 /* s3c24xx_init_irq
655 * Initialise S3C2410 IRQ system
658 void __init s3c24xx_init_irq(void)
660 unsigned long pend;
661 unsigned long last;
662 int irqno;
663 int i;
665 irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
667 /* first, clear all interrupts pending... */
669 last = 0;
670 for (i = 0; i < 4; i++) {
671 pend = __raw_readl(S3C2410_EINTPEND);
673 if (pend == 0 || pend == last)
674 break;
676 __raw_writel(pend, S3C2410_EINTPEND);
677 printk("irq: clearing pending ext status %08x\n", (int)pend);
678 last = pend;
681 last = 0;
682 for (i = 0; i < 4; i++) {
683 pend = __raw_readl(S3C2410_INTPND);
685 if (pend == 0 || pend == last)
686 break;
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;
694 last = 0;
695 for (i = 0; i < 4; i++) {
696 pend = __raw_readl(S3C2410_SUBSRCPND);
698 if (pend == 0 || pend == last)
699 break;
701 printk("irq: clearing subpending status %08x\n", (int)pend);
702 __raw_writel(pend, S3C2410_SUBSRCPND);
703 last = pend;
706 /* register the main interrupts */
708 irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
710 for (irqno = IRQ_BATT_FLT; irqno <= IRQ_ADCPARENT; irqno++) {
711 /* set all the s3c2410 internal irqs */
713 switch (irqno) {
714 /* deal with the special IRQs (cascaded) */
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;
725 case IRQ_RESERVED6:
726 case IRQ_RESERVED24:
727 /* no IRQ here */
728 break;
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);
738 /* setup the cascade irq handlers */
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);
746 /* external interrupts */
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);
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);
762 /* register the uart interrupts */
764 irqdbf("s3c2410: registering external interrupts\n");
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);
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);
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);
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);
794 irqdbf("s3c2410: registered interrupt handlers\n");
797 /* s3c2440 irq code
800 #ifdef CONFIG_CPU_S3C2440
802 /* WDT/AC97 */
804 static void s3c_irq_demux_wdtac97(unsigned int irq,
805 struct irqdesc *desc,
806 struct pt_regs *regs)
808 unsigned int subsrc, submsk;
809 struct irqdesc *mydesc;
811 /* read the current pending interrupts, and the mask
812 * for what it is available */
814 subsrc = __raw_readl(S3C2410_SUBSRCPND);
815 submsk = __raw_readl(S3C2410_INTSUBMSK);
817 subsrc &= ~submsk;
818 subsrc >>= 13;
819 subsrc &= 3;
821 if (subsrc != 0) {
822 if (subsrc & 1) {
823 mydesc = irq_desc + IRQ_S3C2440_WDT;
824 mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
826 if (subsrc & 2) {
827 mydesc = irq_desc + IRQ_S3C2440_AC97;
828 mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
834 #define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0))
836 static void
837 s3c_irq_wdtac97_mask(unsigned int irqno)
839 s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13);
842 static void
843 s3c_irq_wdtac97_unmask(unsigned int irqno)
845 s3c_irqsub_unmask(irqno, INTMSK_WDT);
848 static void
849 s3c_irq_wdtac97_ack(unsigned int irqno)
851 s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13);
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,
860 /* camera irq */
862 static void s3c_irq_demux_cam(unsigned int irq,
863 struct irqdesc *desc,
864 struct pt_regs *regs)
866 unsigned int subsrc, submsk;
867 struct irqdesc *mydesc;
869 /* read the current pending interrupts, and the mask
870 * for what it is available */
872 subsrc = __raw_readl(S3C2410_SUBSRCPND);
873 submsk = __raw_readl(S3C2410_INTSUBMSK);
875 subsrc &= ~submsk;
876 subsrc >>= 11;
877 subsrc &= 3;
879 if (subsrc != 0) {
880 if (subsrc & 1) {
881 mydesc = irq_desc + IRQ_S3C2440_CAM_C;
882 mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
884 if (subsrc & 2) {
885 mydesc = irq_desc + IRQ_S3C2440_CAM_P;
886 mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
891 #define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
893 static void
894 s3c_irq_cam_mask(unsigned int irqno)
896 s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
899 static void
900 s3c_irq_cam_unmask(unsigned int irqno)
902 s3c_irqsub_unmask(irqno, INTMSK_CAM);
905 static void
906 s3c_irq_cam_ack(unsigned int irqno)
908 s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
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,
917 static int s3c2440_irq_add(struct sys_device *sysdev)
919 unsigned int irqno;
921 printk("S3C2440: IRQ Support\n");
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);
927 /* add new chained handler for wdt, ac7 */
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);
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);
939 /* add chained handler for camera */
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);
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);
951 return 0;
954 static struct sysdev_driver s3c2440_irq_driver = {
955 .add = s3c2440_irq_add,
958 static int s3c24xx_irq_driver(void)
960 return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
963 arch_initcall(s3c24xx_irq_driver);
965 #endif /* CONFIG_CPU_S3C2440 */