From 746e8d3b223281f0e5472ab0ad8f59af2221ea9b Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Tue, 18 Nov 2008 20:45:21 +0100 Subject: m68k: mac baboon interrupt enable/disable No-one seems to know how to mask individual baboon interrupts, so we just mask the umbrella IRQ. This will work as long as only the IDE driver uses the baboon chip (it can't deadlock). Use mac_enable_irq/mac_disable_irq rather than enable_irq/disable_irq because the latter routines count the depth of nested calls which triggers a warning and call trace because IRQ_NUBUS_C is enabled twice in a row (once when the baboon handler is registered, and once when the IDE IRQ is registered). Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven --- arch/m68k/mac/baboon.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) (limited to 'arch/m68k/mac/baboon.c') diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index c7b25b0..245d16d 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c @@ -18,11 +18,14 @@ #include #include -/* #define DEBUG_BABOON */ /* #define DEBUG_IRQS */ +extern void mac_enable_irq(unsigned int); +extern void mac_disable_irq(unsigned int); + int baboon_present; static volatile struct baboon *baboon; +static unsigned char baboon_disabled; #if 0 extern int macide_ack_intr(struct ata_channel *); @@ -88,34 +91,51 @@ static irqreturn_t baboon_irq(int irq, void *dev_id) void __init baboon_register_interrupts(void) { - request_irq(IRQ_NUBUS_C, baboon_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, - "baboon", (void *) baboon); + baboon_disabled = 0; + request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon); } -void baboon_irq_enable(int irq) { +/* + * The means for masking individual baboon interrupts remains a mystery, so + * enable the umbrella interrupt only when no baboon interrupt is disabled. + */ + +void baboon_irq_enable(int irq) +{ + int irq_idx = IRQ_IDX(irq); + #ifdef DEBUG_IRQUSE printk("baboon_irq_enable(%d)\n", irq); #endif - /* FIXME: figure out how to mask and unmask baboon interrupt sources */ - enable_irq(IRQ_NUBUS_C); + + baboon_disabled &= ~(1 << irq_idx); + if (!baboon_disabled) + mac_enable_irq(IRQ_NUBUS_C); } -void baboon_irq_disable(int irq) { +void baboon_irq_disable(int irq) +{ + int irq_idx = IRQ_IDX(irq); + #ifdef DEBUG_IRQUSE printk("baboon_irq_disable(%d)\n", irq); #endif - disable_irq(IRQ_NUBUS_C); + + baboon_disabled |= 1 << irq_idx; + if (baboon_disabled) + mac_disable_irq(IRQ_NUBUS_C); } -void baboon_irq_clear(int irq) { - int irq_idx = IRQ_IDX(irq); +void baboon_irq_clear(int irq) +{ + int irq_idx = IRQ_IDX(irq); baboon->mb_ifr &= ~(1 << irq_idx); } int baboon_irq_pending(int irq) { - int irq_idx = IRQ_IDX(irq); + int irq_idx = IRQ_IDX(irq); return baboon->mb_ifr & (1 << irq_idx); } -- cgit v1.1