diff options
author | Rafael Ignacio Zurita <rizurita@yahoo.com> | 2009-03-19 22:08:22 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-03-20 05:57:48 -0400 |
commit | 3bf509230a626d11cba0e0145f552918092f586d (patch) | |
tree | 89f12de362f46871e6238bc2ce6516f103e966a9 | |
parent | 7a8fe8e320251d25274e89f610ffee936769250a (diff) |
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>
-rw-r--r-- | arch/sh/boards/mach-hp6xx/setup.c | 1 | ||||
-rw-r--r-- | arch/sh/cchips/hd6446x/hd64461.c | 30 | ||||
-rw-r--r-- | arch/sh/include/asm/hd64461.h | 1 |
3 files changed, 17 insertions, 15 deletions
diff --git a/arch/sh/boards/mach-hp6xx/setup.c b/arch/sh/boards/mach-hp6xx/setup.c index 746742bdc014..8f305b36358b 100644 --- a/arch/sh/boards/mach-hp6xx/setup.c +++ b/arch/sh/boards/mach-hp6xx/setup.c | |||
@@ -115,7 +115,6 @@ static struct sh_machine_vector mv_hp6xx __initmv = { | |||
115 | .mv_setup = hp6xx_setup, | 115 | .mv_setup = hp6xx_setup, |
116 | /* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */ | 116 | /* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */ |
117 | .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6, | 117 | .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6, |
118 | .mv_irq_demux = hd64461_irq_demux, | ||
119 | /* Enable IRQ0 -> IRQ3 in IRQ_MODE */ | 118 | /* Enable IRQ0 -> IRQ3 in IRQ_MODE */ |
120 | .mv_init_irq = hp6xx_init_irq, | 119 | .mv_init_irq = hp6xx_init_irq, |
121 | }; | 120 | }; |
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 = { | |||
53 | .unmask = hd64461_unmask_irq, | 53 | .unmask = hd64461_unmask_irq, |
54 | }; | 54 | }; |
55 | 55 | ||
56 | int hd64461_irq_demux(int irq) | 56 | static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc) |
57 | { | 57 | { |
58 | if (irq == CONFIG_HD64461_IRQ) { | 58 | unsigned short intv = ctrl_inw(HD64461_NIRR); |
59 | unsigned short bit; | 59 | struct irq_desc *ext_desc; |
60 | unsigned short nirr = inw(HD64461_NIRR); | 60 | unsigned int ext_irq = HD64461_IRQBASE; |
61 | unsigned short nimr = inw(HD64461_NIMR); | 61 | |
62 | int i; | 62 | intv &= (1 << HD64461_IRQ_NUM) - 1; |
63 | 63 | ||
64 | nirr &= ~nimr; | 64 | while (intv) { |
65 | for (bit = 1, i = 0; i < 16; bit <<= 1, i++) | 65 | if (intv & 1) { |
66 | if (nirr & bit) | 66 | ext_desc = irq_desc + ext_irq; |
67 | break; | 67 | handle_level_irq(ext_irq, ext_desc); |
68 | irq = HD64461_IRQBASE + i; | 68 | } |
69 | intv >>= 1; | ||
70 | ext_irq++; | ||
69 | } | 71 | } |
70 | return irq; | ||
71 | } | 72 | } |
72 | 73 | ||
73 | int __init setup_hd64461(void) | 74 | int __init setup_hd64461(void) |
@@ -93,6 +94,9 @@ int __init setup_hd64461(void) | |||
93 | set_irq_chip_and_handler(i, &hd64461_irq_chip, | 94 | set_irq_chip_and_handler(i, &hd64461_irq_chip, |
94 | handle_level_irq); | 95 | handle_level_irq); |
95 | 96 | ||
97 | set_irq_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux); | ||
98 | set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW); | ||
99 | |||
96 | #ifdef CONFIG_HD64461_ENABLER | 100 | #ifdef CONFIG_HD64461_ENABLER |
97 | printk(KERN_INFO "HD64461: enabling PCMCIA devices\n"); | 101 | printk(KERN_INFO "HD64461: enabling PCMCIA devices\n"); |
98 | __raw_writeb(0x4c, HD64461_PCC1CSCIER); | 102 | __raw_writeb(0x4c, HD64461_PCC1CSCIER); |
diff --git a/arch/sh/include/asm/hd64461.h b/arch/sh/include/asm/hd64461.h index 8c1353baf00f..52b4b6238277 100644 --- a/arch/sh/include/asm/hd64461.h +++ b/arch/sh/include/asm/hd64461.h | |||
@@ -242,7 +242,6 @@ | |||
242 | #include <asm/io_generic.h> | 242 | #include <asm/io_generic.h> |
243 | 243 | ||
244 | /* arch/sh/cchips/hd6446x/hd64461/setup.c */ | 244 | /* arch/sh/cchips/hd6446x/hd64461/setup.c */ |
245 | int hd64461_irq_demux(int irq); | ||
246 | void hd64461_register_irq_demux(int irq, | 245 | void hd64461_register_irq_demux(int irq, |
247 | int (*demux) (int irq, void *dev), void *dev); | 246 | int (*demux) (int irq, void *dev), void *dev); |
248 | void hd64461_unregister_irq_demux(int irq); | 247 | void hd64461_unregister_irq_demux(int irq); |