diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2008-11-18 14:45:21 -0500 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2008-12-28 14:00:04 -0500 |
commit | 746e8d3b223281f0e5472ab0ad8f59af2221ea9b (patch) | |
tree | 47cd58b80407be264b5e55174771b674c2289de6 /arch/m68k/mac | |
parent | 429dbf53bca49b110f1058f0d9417a59115c41b8 (diff) |
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 <fthain@telegraphics.com.au>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'arch/m68k/mac')
-rw-r--r-- | arch/m68k/mac/baboon.c | 42 | ||||
-rw-r--r-- | arch/m68k/mac/macints.c | 8 |
2 files changed, 35 insertions, 15 deletions
diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index c7b25b0aacff..245d16d078ad 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c | |||
@@ -18,11 +18,14 @@ | |||
18 | #include <asm/macints.h> | 18 | #include <asm/macints.h> |
19 | #include <asm/mac_baboon.h> | 19 | #include <asm/mac_baboon.h> |
20 | 20 | ||
21 | /* #define DEBUG_BABOON */ | ||
22 | /* #define DEBUG_IRQS */ | 21 | /* #define DEBUG_IRQS */ |
23 | 22 | ||
23 | extern void mac_enable_irq(unsigned int); | ||
24 | extern void mac_disable_irq(unsigned int); | ||
25 | |||
24 | int baboon_present; | 26 | int baboon_present; |
25 | static volatile struct baboon *baboon; | 27 | static volatile struct baboon *baboon; |
28 | static unsigned char baboon_disabled; | ||
26 | 29 | ||
27 | #if 0 | 30 | #if 0 |
28 | extern int macide_ack_intr(struct ata_channel *); | 31 | extern int macide_ack_intr(struct ata_channel *); |
@@ -88,34 +91,51 @@ static irqreturn_t baboon_irq(int irq, void *dev_id) | |||
88 | 91 | ||
89 | void __init baboon_register_interrupts(void) | 92 | void __init baboon_register_interrupts(void) |
90 | { | 93 | { |
91 | request_irq(IRQ_NUBUS_C, baboon_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, | 94 | baboon_disabled = 0; |
92 | "baboon", (void *) baboon); | 95 | request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon); |
93 | } | 96 | } |
94 | 97 | ||
95 | void baboon_irq_enable(int irq) { | 98 | /* |
99 | * The means for masking individual baboon interrupts remains a mystery, so | ||
100 | * enable the umbrella interrupt only when no baboon interrupt is disabled. | ||
101 | */ | ||
102 | |||
103 | void baboon_irq_enable(int irq) | ||
104 | { | ||
105 | int irq_idx = IRQ_IDX(irq); | ||
106 | |||
96 | #ifdef DEBUG_IRQUSE | 107 | #ifdef DEBUG_IRQUSE |
97 | printk("baboon_irq_enable(%d)\n", irq); | 108 | printk("baboon_irq_enable(%d)\n", irq); |
98 | #endif | 109 | #endif |
99 | /* FIXME: figure out how to mask and unmask baboon interrupt sources */ | 110 | |
100 | enable_irq(IRQ_NUBUS_C); | 111 | baboon_disabled &= ~(1 << irq_idx); |
112 | if (!baboon_disabled) | ||
113 | mac_enable_irq(IRQ_NUBUS_C); | ||
101 | } | 114 | } |
102 | 115 | ||
103 | void baboon_irq_disable(int irq) { | 116 | void baboon_irq_disable(int irq) |
117 | { | ||
118 | int irq_idx = IRQ_IDX(irq); | ||
119 | |||
104 | #ifdef DEBUG_IRQUSE | 120 | #ifdef DEBUG_IRQUSE |
105 | printk("baboon_irq_disable(%d)\n", irq); | 121 | printk("baboon_irq_disable(%d)\n", irq); |
106 | #endif | 122 | #endif |
107 | disable_irq(IRQ_NUBUS_C); | 123 | |
124 | baboon_disabled |= 1 << irq_idx; | ||
125 | if (baboon_disabled) | ||
126 | mac_disable_irq(IRQ_NUBUS_C); | ||
108 | } | 127 | } |
109 | 128 | ||
110 | void baboon_irq_clear(int irq) { | 129 | void baboon_irq_clear(int irq) |
111 | int irq_idx = IRQ_IDX(irq); | 130 | { |
131 | int irq_idx = IRQ_IDX(irq); | ||
112 | 132 | ||
113 | baboon->mb_ifr &= ~(1 << irq_idx); | 133 | baboon->mb_ifr &= ~(1 << irq_idx); |
114 | } | 134 | } |
115 | 135 | ||
116 | int baboon_irq_pending(int irq) | 136 | int baboon_irq_pending(int irq) |
117 | { | 137 | { |
118 | int irq_idx = IRQ_IDX(irq); | 138 | int irq_idx = IRQ_IDX(irq); |
119 | 139 | ||
120 | return baboon->mb_ifr & (1 << irq_idx); | 140 | return baboon->mb_ifr & (1 << irq_idx); |
121 | } | 141 | } |
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index e17b8d56ce04..82e560c076ce 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c | |||
@@ -214,8 +214,8 @@ irqreturn_t mac_debug_handler(int, void *); | |||
214 | 214 | ||
215 | /* #define DEBUG_MACINTS */ | 215 | /* #define DEBUG_MACINTS */ |
216 | 216 | ||
217 | static void mac_enable_irq(unsigned int irq); | 217 | void mac_enable_irq(unsigned int irq); |
218 | static void mac_disable_irq(unsigned int irq); | 218 | void mac_disable_irq(unsigned int irq); |
219 | 219 | ||
220 | static struct irq_controller mac_irq_controller = { | 220 | static struct irq_controller mac_irq_controller = { |
221 | .name = "mac", | 221 | .name = "mac", |
@@ -274,7 +274,7 @@ void __init mac_init_IRQ(void) | |||
274 | * These routines are just dispatchers to the VIA/OSS/PSC routines. | 274 | * These routines are just dispatchers to the VIA/OSS/PSC routines. |
275 | */ | 275 | */ |
276 | 276 | ||
277 | static void mac_enable_irq(unsigned int irq) | 277 | void mac_enable_irq(unsigned int irq) |
278 | { | 278 | { |
279 | int irq_src = IRQ_SRC(irq); | 279 | int irq_src = IRQ_SRC(irq); |
280 | 280 | ||
@@ -307,7 +307,7 @@ static void mac_enable_irq(unsigned int irq) | |||
307 | } | 307 | } |
308 | } | 308 | } |
309 | 309 | ||
310 | static void mac_disable_irq(unsigned int irq) | 310 | void mac_disable_irq(unsigned int irq) |
311 | { | 311 | { |
312 | int irq_src = IRQ_SRC(irq); | 312 | int irq_src = IRQ_SRC(irq); |
313 | 313 | ||