aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2006-06-24 16:21:37 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-06-24 16:21:37 -0400
commita019f4a9a7b4ec4986918e9aefa06815cf77b714 (patch)
tree52f98219bc0d86e6c55e48513a6dcfa93a0cb44c /arch
parent22346aea8d39372d6fd207468701e90bf546b882 (diff)
[ARM] 3645/1: S3C2412: irq support for external interrupts
Patch from Ben Dooks Move the decoding of the IRQ_EXT4 and above out of the entry macro, and into an chained irq handler as the EXTINT registers move depending on the CPU being used. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-s3c2410/irq.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index 46465742ed79..6822dc7f7799 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -191,13 +191,9 @@ static struct irqchip s3c_irq_chip = {
191 .ack = s3c_irq_ack, 191 .ack = s3c_irq_ack,
192 .mask = s3c_irq_mask, 192 .mask = s3c_irq_mask,
193 .unmask = s3c_irq_unmask, 193 .unmask = s3c_irq_unmask,
194 .set_wake = s3c_irq_wake 194 .set_wake = s3c_irq_wake
195}; 195};
196 196
197/* S3C2410_EINTMASK
198 * S3C2410_EINTPEND
199 */
200
201static void 197static void
202s3c_irqext_mask(unsigned int irqno) 198s3c_irqext_mask(unsigned int irqno)
203{ 199{
@@ -205,9 +201,9 @@ s3c_irqext_mask(unsigned int irqno)
205 201
206 irqno -= EXTINT_OFF; 202 irqno -= EXTINT_OFF;
207 203
208 mask = __raw_readl(S3C2410_EINTMASK); 204 mask = __raw_readl(S3C24XX_EINTMASK);
209 mask |= ( 1UL << irqno); 205 mask |= ( 1UL << irqno);
210 __raw_writel(mask, S3C2410_EINTMASK); 206 __raw_writel(mask, S3C24XX_EINTMASK);
211 207
212 if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) { 208 if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) {
213 /* check to see if all need masking */ 209 /* check to see if all need masking */
@@ -232,11 +228,11 @@ s3c_irqext_ack(unsigned int irqno)
232 bit = 1UL << (irqno - EXTINT_OFF); 228 bit = 1UL << (irqno - EXTINT_OFF);
233 229
234 230
235 mask = __raw_readl(S3C2410_EINTMASK); 231 mask = __raw_readl(S3C24XX_EINTMASK);
236 232
237 __raw_writel(bit, S3C2410_EINTPEND); 233 __raw_writel(bit, S3C24XX_EINTPEND);
238 234
239 req = __raw_readl(S3C2410_EINTPEND); 235 req = __raw_readl(S3C24XX_EINTPEND);
240 req &= ~mask; 236 req &= ~mask;
241 237
242 /* not sure if we should be acking the parent irq... */ 238 /* not sure if we should be acking the parent irq... */
@@ -257,9 +253,9 @@ s3c_irqext_unmask(unsigned int irqno)
257 253
258 irqno -= EXTINT_OFF; 254 irqno -= EXTINT_OFF;
259 255
260 mask = __raw_readl(S3C2410_EINTMASK); 256 mask = __raw_readl(S3C24XX_EINTMASK);
261 mask &= ~( 1UL << irqno); 257 mask &= ~( 1UL << irqno);
262 __raw_writel(mask, S3C2410_EINTMASK); 258 __raw_writel(mask, S3C24XX_EINTMASK);
263 259
264 s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23); 260 s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23);
265} 261}
@@ -572,6 +568,23 @@ s3c_irq_demux_uart2(unsigned int irq,
572 s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs); 568 s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs);
573} 569}
574 570
571static void
572s3c_irq_demux_extint(unsigned int irq,
573 struct irqdesc *desc,
574 struct pt_regs *regs)
575{
576 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
577 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
578
579 eintpnd &= ~eintmsk;
580
581 if (eintpnd) {
582 irq = fls(eintpnd);
583 irq += (IRQ_EINT4 - (4 + 1));
584
585 desc_handle_irq(irq, irq_desc + irq, regs);
586 }
587}
575 588
576/* s3c24xx_init_irq 589/* s3c24xx_init_irq
577 * 590 *
@@ -591,12 +604,12 @@ void __init s3c24xx_init_irq(void)
591 604
592 last = 0; 605 last = 0;
593 for (i = 0; i < 4; i++) { 606 for (i = 0; i < 4; i++) {
594 pend = __raw_readl(S3C2410_EINTPEND); 607 pend = __raw_readl(S3C24XX_EINTPEND);
595 608
596 if (pend == 0 || pend == last) 609 if (pend == 0 || pend == last)
597 break; 610 break;
598 611
599 __raw_writel(pend, S3C2410_EINTPEND); 612 __raw_writel(pend, S3C24XX_EINTPEND);
600 printk("irq: clearing pending ext status %08x\n", (int)pend); 613 printk("irq: clearing pending ext status %08x\n", (int)pend);
601 last = pend; 614 last = pend;
602 } 615 }
@@ -630,12 +643,14 @@ void __init s3c24xx_init_irq(void)
630 643
631 irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n"); 644 irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
632 645
633 for (irqno = IRQ_BATT_FLT; irqno <= IRQ_ADCPARENT; irqno++) { 646 for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
634 /* set all the s3c2410 internal irqs */ 647 /* set all the s3c2410 internal irqs */
635 648
636 switch (irqno) { 649 switch (irqno) {
637 /* deal with the special IRQs (cascaded) */ 650 /* deal with the special IRQs (cascaded) */
638 651
652 case IRQ_EINT4t7:
653 case IRQ_EINT8t23:
639 case IRQ_UART0: 654 case IRQ_UART0:
640 case IRQ_UART1: 655 case IRQ_UART1:
641 case IRQ_UART2: 656 case IRQ_UART2:
@@ -659,12 +674,14 @@ void __init s3c24xx_init_irq(void)
659 674
660 /* setup the cascade irq handlers */ 675 /* setup the cascade irq handlers */
661 676
677 set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint);
678 set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint);
679
662 set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); 680 set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
663 set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); 681 set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
664 set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2); 682 set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
665 set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc); 683 set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
666 684
667
668 /* external interrupts */ 685 /* external interrupts */
669 686
670 for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { 687 for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {