aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c2410/irq.c
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2006-09-28 15:40:50 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-09-28 15:48:49 -0400
commit38e0533ce87a58e25f959e6d0958478b6a137794 (patch)
treec9c1f02946b3ad39cded1c6ad8d0a815c3f61f41 /arch/arm/mach-s3c2410/irq.c
parent1f51c10c5e85050506663bce1d69513eb901db87 (diff)
[ARM] 3871/1: S3C24XX: Fix ordering of EINT4..23
The demux code for the IRQ EINTs above 3 was using find last set instead of finding first set. Also fix it so that we only check EINT4..7 when the parent EINT4t7 goes off, and the 8..23 when EINT8t23 goes off. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-s3c2410/irq.c')
-rw-r--r--arch/arm/mach-s3c2410/irq.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index 9c7463bf8f86..0ecfef3c7514 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -569,18 +569,46 @@ s3c_irq_demux_uart2(unsigned int irq,
569} 569}
570 570
571static void 571static void
572s3c_irq_demux_extint(unsigned int irq, 572s3c_irq_demux_extint8(unsigned int irq,
573 struct irqdesc *desc, 573 struct irqdesc *desc,
574 struct pt_regs *regs) 574 struct pt_regs *regs)
575{ 575{
576 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); 576 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
577 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); 577 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
578 578
579 eintpnd &= ~eintmsk; 579 eintpnd &= ~eintmsk;
580 eintpnd &= ~0xff; /* ignore lower irqs */
580 581
581 if (eintpnd) { 582 /* we may as well handle all the pending IRQs here */
582 irq = fls(eintpnd); 583
583 irq += (IRQ_EINT4 - (4 + 1)); 584 while (eintpnd) {
585 irq = __ffs(eintpnd);
586 eintpnd &= ~(1<<irq);
587
588 irq += (IRQ_EINT4 - 4);
589 desc_handle_irq(irq, irq_desc + irq, regs);
590 }
591
592}
593
594static void
595s3c_irq_demux_extint4t7(unsigned int irq,
596 struct irqdesc *desc,
597 struct pt_regs *regs)
598{
599 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
600 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
601
602 eintpnd &= ~eintmsk;
603 eintpnd &= 0xff; /* only lower irqs */
604
605 /* we may as well handle all the pending IRQs here */
606
607 while (eintpnd) {
608 irq = __ffs(eintpnd);
609 eintpnd &= ~(1<<irq);
610
611 irq += (IRQ_EINT4 - 4);
584 612
585 desc_handle_irq(irq, irq_desc + irq, regs); 613 desc_handle_irq(irq, irq_desc + irq, regs);
586 } 614 }
@@ -727,8 +755,8 @@ void __init s3c24xx_init_irq(void)
727 755
728 /* setup the cascade irq handlers */ 756 /* setup the cascade irq handlers */
729 757
730 set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint); 758 set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
731 set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint); 759 set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
732 760
733 set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); 761 set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
734 set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); 762 set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);