summary refs log tree commit diff
path: root/arch/sh/cchips
diff options
context:
space:
mode:
authorRafael Ignacio Zurita <rizurita@yahoo.com>2009-03-20 02:08:22 +0000
committerPaul Mundt <lethal@linux-sh.org>2009-03-20 18:57:48 +0900
commit3bf509230a626d11cba0e0145f552918092f586d (patch)
tree89f12de362f46871e6238bc2ce6516f103e966a9 /arch/sh/cchips
parent7a8fe8e320251d25274e89f610ffee936769250a (diff)
downloadlinux-3bf509230a626d11cba0e0145f552918092f586d.tar.gz
sh: fix the HD64461 level-triggered interrupts handling
Rework the hd64461 demuxer code to fix the HD64461 level-triggered
interrupts handling, using handle_level_irq() as needed.

Signed-off-by: Rafael Ignacio Zurita <rizurita@yahoo.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/cchips')
-rw-r--r--arch/sh/cchips/hd6446x/hd64461.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
index 27ceeb948bb1..25ef91061521 100644
--- a/arch/sh/cchips/hd6446x/hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461.c
@@ -53,21 +53,22 @@ static struct irq_chip hd64461_irq_chip = {
 	.unmask		= hd64461_unmask_irq,
 };
 
-int hd64461_irq_demux(int irq)
+static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
-	if (irq == CONFIG_HD64461_IRQ) {
-		unsigned short bit;
-		unsigned short nirr = inw(HD64461_NIRR);
-		unsigned short nimr = inw(HD64461_NIMR);
-		int i;
-
-		nirr &= ~nimr;
-		for (bit = 1, i = 0; i < 16; bit <<= 1, i++)
-			if (nirr & bit)
-				break;
-		irq = HD64461_IRQBASE + i;
+	unsigned short intv = ctrl_inw(HD64461_NIRR);
+	struct irq_desc *ext_desc;
+	unsigned int ext_irq = HD64461_IRQBASE;
+
+	intv &= (1 << HD64461_IRQ_NUM) - 1;
+
+	while (intv) {
+		if (intv & 1) {
+			ext_desc = irq_desc + ext_irq;
+			handle_level_irq(ext_irq, ext_desc);
+		}
+		intv >>= 1;
+		ext_irq++;
 	}
-	return irq;
 }
 
 int __init setup_hd64461(void)
@@ -93,6 +94,9 @@ int __init setup_hd64461(void)
 		set_irq_chip_and_handler(i, &hd64461_irq_chip,
 					 handle_level_irq);
 
+	set_irq_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux);
+	set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW);
+
 #ifdef CONFIG_HD64461_ENABLER
 	printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
 	__raw_writeb(0x4c, HD64461_PCC1CSCIER);