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>
This commit is contained in:
parent
7a8fe8e320
commit
3bf509230a
|
@ -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 = {
|
||||||
.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;
|
|
||||||
|
|
||||||
nirr &= ~nimr;
|
intv &= (1 << HD64461_IRQ_NUM) - 1;
|
||||||
for (bit = 1, i = 0; i < 16; bit <<= 1, i++)
|
|
||||||
if (nirr & bit)
|
while (intv) {
|
||||||
break;
|
if (intv & 1) {
|
||||||
irq = HD64461_IRQBASE + i;
|
ext_desc = irq_desc + ext_irq;
|
||||||
|
handle_level_irq(ext_irq, ext_desc);
|
||||||
|
}
|
||||||
|
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)
|
||||||
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 @@
|
||||||
#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);
|
||||||
|
|
Loading…
Reference in a new issue