Commit 3bf50923 authored by Rafael Ignacio Zurita's avatar Rafael Ignacio Zurita Committed by Paul Mundt

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: default avatarRafael Ignacio Zurita <rizurita@yahoo.com>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 7a8fe8e3
...@@ -115,7 +115,6 @@ static struct sh_machine_vector mv_hp6xx __initmv = { ...@@ -115,7 +115,6 @@ static struct sh_machine_vector mv_hp6xx __initmv = {
.mv_setup = hp6xx_setup, .mv_setup = hp6xx_setup,
/* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */ /* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */
.mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6, .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6,
.mv_irq_demux = hd64461_irq_demux,
/* Enable IRQ0 -> IRQ3 in IRQ_MODE */ /* Enable IRQ0 -> IRQ3 in IRQ_MODE */
.mv_init_irq = hp6xx_init_irq, .mv_init_irq = hp6xx_init_irq,
}; };
...@@ -53,21 +53,22 @@ static struct irq_chip hd64461_irq_chip = { ...@@ -53,21 +53,22 @@ static struct irq_chip hd64461_irq_chip = {
.unmask = hd64461_unmask_irq, .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 intv = ctrl_inw(HD64461_NIRR);
unsigned short bit; struct irq_desc *ext_desc;
unsigned short nirr = inw(HD64461_NIRR); unsigned int ext_irq = HD64461_IRQBASE;
unsigned short nimr = inw(HD64461_NIMR);
int i; intv &= (1 << HD64461_IRQ_NUM) - 1;
nirr &= ~nimr; while (intv) {
for (bit = 1, i = 0; i < 16; bit <<= 1, i++) if (intv & 1) {
if (nirr & bit) ext_desc = irq_desc + ext_irq;
break; handle_level_irq(ext_irq, ext_desc);
irq = HD64461_IRQBASE + i; }
intv >>= 1;
ext_irq++;
} }
return irq;
} }
int __init setup_hd64461(void) int __init setup_hd64461(void)
...@@ -93,6 +94,9 @@ int __init setup_hd64461(void) ...@@ -93,6 +94,9 @@ int __init setup_hd64461(void)
set_irq_chip_and_handler(i, &hd64461_irq_chip, set_irq_chip_and_handler(i, &hd64461_irq_chip,
handle_level_irq); 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 #ifdef CONFIG_HD64461_ENABLER
printk(KERN_INFO "HD64461: enabling PCMCIA devices\n"); printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
__raw_writeb(0x4c, HD64461_PCC1CSCIER); __raw_writeb(0x4c, HD64461_PCC1CSCIER);
......
...@@ -242,7 +242,6 @@ ...@@ -242,7 +242,6 @@
#include <asm/io_generic.h> #include <asm/io_generic.h>
/* arch/sh/cchips/hd6446x/hd64461/setup.c */ /* arch/sh/cchips/hd6446x/hd64461/setup.c */
int hd64461_irq_demux(int irq);
void hd64461_register_irq_demux(int irq, void hd64461_register_irq_demux(int irq,
int (*demux) (int irq, void *dev), void *dev); int (*demux) (int irq, void *dev), void *dev);
void hd64461_unregister_irq_demux(int irq); void hd64461_unregister_irq_demux(int irq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment