瀏覽代碼

[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>
Ben Dooks 19 年之前
父節點
當前提交
38e0533ce8
共有 1 個文件被更改,包括 36 次插入8 次删除
  1. 36 8
      arch/arm/mach-s3c2410/irq.c

+ 36 - 8
arch/arm/mach-s3c2410/irq.c

@@ -569,18 +569,46 @@ s3c_irq_demux_uart2(unsigned int irq,
 }
 }
 
 
 static void
 static void
-s3c_irq_demux_extint(unsigned int irq,
-		     struct irqdesc *desc,
-		     struct pt_regs *regs)
+s3c_irq_demux_extint8(unsigned int irq,
+		      struct irqdesc *desc,
+		      struct pt_regs *regs)
 {
 {
 	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
 	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
 	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
 	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
 
 
 	eintpnd &= ~eintmsk;
 	eintpnd &= ~eintmsk;
+	eintpnd &= ~0xff;	/* ignore lower irqs */
 
 
-	if (eintpnd) {
-		irq = fls(eintpnd);
-		irq += (IRQ_EINT4 - (4 + 1));
+	/* we may as well handle all the pending IRQs here */
+
+	while (eintpnd) {
+		irq = __ffs(eintpnd);
+		eintpnd &= ~(1<<irq);
+
+		irq += (IRQ_EINT4 - 4);
+		desc_handle_irq(irq, irq_desc + irq, regs);
+	}
+
+}
+
+static void
+s3c_irq_demux_extint4t7(unsigned int irq,
+			struct irqdesc *desc,
+			struct pt_regs *regs)
+{
+	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
+	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
+
+	eintpnd &= ~eintmsk;
+	eintpnd &= 0xff;	/* only lower irqs */
+
+	/* we may as well handle all the pending IRQs here */
+
+	while (eintpnd) {
+		irq = __ffs(eintpnd);
+		eintpnd &= ~(1<<irq);
+
+		irq += (IRQ_EINT4 - 4);
 
 
 		desc_handle_irq(irq, irq_desc + irq, regs);
 		desc_handle_irq(irq, irq_desc + irq, regs);
 	}
 	}
@@ -727,8 +755,8 @@ void __init s3c24xx_init_irq(void)
 
 
 	/* setup the cascade irq handlers */
 	/* setup the cascade irq handlers */
 
 
-	set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint);
-	set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint);
+	set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
+	set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
 
 
 	set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
 	set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
 	set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
 	set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);