diff options
Diffstat (limited to 'arch/m68k')
-rw-r--r-- | arch/m68k/amiga/amiints.c | 4 | ||||
-rw-r--r-- | arch/m68k/bvme6000/bvmeints.c | 1 | ||||
-rw-r--r-- | arch/m68k/kernel/ints.c | 171 | ||||
-rw-r--r-- | arch/m68k/mac/config.c | 15 | ||||
-rw-r--r-- | arch/m68k/mac/macints.c | 7 | ||||
-rw-r--r-- | arch/m68k/mvme147/147ints.c | 1 | ||||
-rw-r--r-- | arch/m68k/mvme16x/16xints.c | 1 | ||||
-rw-r--r-- | arch/m68k/q40/config.c | 2 | ||||
-rw-r--r-- | arch/m68k/q40/q40ints.c | 17 |
9 files changed, 127 insertions, 92 deletions
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index d02458ebd345..e2d47b7bdfc1 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/sched.h> | 40 | #include <linux/sched.h> |
41 | #include <linux/kernel_stat.h> | 41 | #include <linux/kernel_stat.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/interrupt.h> | ||
43 | #include <linux/errno.h> | 44 | #include <linux/errno.h> |
44 | #include <linux/seq_file.h> | 45 | #include <linux/seq_file.h> |
45 | 46 | ||
@@ -484,13 +485,10 @@ static irqreturn_t ami_int7(int irq, void *dev_id, struct pt_regs *fp) | |||
484 | } | 485 | } |
485 | 486 | ||
486 | irqreturn_t (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { | 487 | irqreturn_t (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { |
487 | [0] = ami_badint, | ||
488 | [1] = ami_int1, | 488 | [1] = ami_int1, |
489 | [2] = ami_badint, | ||
490 | [3] = ami_int3, | 489 | [3] = ami_int3, |
491 | [4] = ami_int4, | 490 | [4] = ami_int4, |
492 | [5] = ami_int5, | 491 | [5] = ami_int5, |
493 | [6] = ami_badint, | ||
494 | [7] = ami_int7 | 492 | [7] = ami_int7 |
495 | }; | 493 | }; |
496 | 494 | ||
diff --git a/arch/m68k/bvme6000/bvmeints.c b/arch/m68k/bvme6000/bvmeints.c index 298a8df02664..b015fdc1b0cb 100644 --- a/arch/m68k/bvme6000/bvmeints.c +++ b/arch/m68k/bvme6000/bvmeints.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/interrupt.h> | ||
17 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
18 | 19 | ||
19 | #include <asm/ptrace.h> | 20 | #include <asm/ptrace.h> |
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 3ce7c6166bb9..c7f6ee67fd5a 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c | |||
@@ -45,7 +45,15 @@ | |||
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | /* table for system interrupt handlers */ | 47 | /* table for system interrupt handlers */ |
48 | static irq_handler_t irq_list[SYS_IRQS]; | 48 | static struct irq_node *irq_list[SYS_IRQS]; |
49 | static struct irq_controller *irq_controller[SYS_IRQS]; | ||
50 | |||
51 | static struct irq_controller auto_irq_controller = { | ||
52 | .name = "auto", | ||
53 | .lock = SPIN_LOCK_UNLOCKED, | ||
54 | .startup = m68k_irq_startup, | ||
55 | .shutdown = m68k_irq_shutdown, | ||
56 | }; | ||
49 | 57 | ||
50 | static const char *default_names[SYS_IRQS] = { | 58 | static const char *default_names[SYS_IRQS] = { |
51 | [0] = "spurious int", | 59 | [0] = "spurious int", |
@@ -101,17 +109,13 @@ void __init init_IRQ(void) | |||
101 | hardirq_mask_is_broken(); | 109 | hardirq_mask_is_broken(); |
102 | } | 110 | } |
103 | 111 | ||
104 | for (i = 0; i < SYS_IRQS; i++) { | 112 | for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) { |
105 | if (mach_default_handler) | 113 | irq_controller[i] = &auto_irq_controller; |
106 | irq_list[i].handler = (*mach_default_handler)[i]; | 114 | if (mach_default_handler && (*mach_default_handler)[i]) |
107 | irq_list[i].flags = 0; | 115 | cpu_request_irq(i, (*mach_default_handler)[i], |
108 | irq_list[i].dev_id = NULL; | 116 | 0, default_names[i], NULL); |
109 | irq_list[i].devname = default_names[i]; | ||
110 | } | 117 | } |
111 | 118 | ||
112 | for (i = 0; i < NUM_IRQ_NODES; i++) | ||
113 | nodes[i].handler = NULL; | ||
114 | |||
115 | mach_init_IRQ (); | 119 | mach_init_IRQ (); |
116 | } | 120 | } |
117 | 121 | ||
@@ -120,9 +124,12 @@ irq_node_t *new_irq_node(void) | |||
120 | irq_node_t *node; | 124 | irq_node_t *node; |
121 | short i; | 125 | short i; |
122 | 126 | ||
123 | for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) | 127 | for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) { |
124 | if (!node->handler) | 128 | if (!node->handler) { |
129 | memset(node, 0, sizeof(*node)); | ||
125 | return node; | 130 | return node; |
131 | } | ||
132 | } | ||
126 | 133 | ||
127 | printk ("new_irq_node: out of nodes\n"); | 134 | printk ("new_irq_node: out of nodes\n"); |
128 | return NULL; | 135 | return NULL; |
@@ -149,55 +156,115 @@ void free_irq(unsigned int irq, void *dev_id) | |||
149 | 156 | ||
150 | EXPORT_SYMBOL(free_irq); | 157 | EXPORT_SYMBOL(free_irq); |
151 | 158 | ||
152 | int cpu_request_irq(unsigned int irq, | 159 | int setup_irq(unsigned int irq, struct irq_node *node) |
153 | irqreturn_t (*handler)(int, void *, struct pt_regs *), | ||
154 | unsigned long flags, const char *devname, void *dev_id) | ||
155 | { | 160 | { |
156 | if (irq < IRQ_AUTO_1 || irq > IRQ_AUTO_7) { | 161 | struct irq_controller *contr; |
162 | struct irq_node **prev; | ||
163 | unsigned long flags; | ||
164 | |||
165 | if (irq >= SYS_IRQS || !(contr = irq_controller[irq])) { | ||
157 | printk("%s: Incorrect IRQ %d from %s\n", | 166 | printk("%s: Incorrect IRQ %d from %s\n", |
158 | __FUNCTION__, irq, devname); | 167 | __FUNCTION__, irq, node->devname); |
159 | return -ENXIO; | 168 | return -ENXIO; |
160 | } | 169 | } |
161 | 170 | ||
162 | #if 0 | 171 | spin_lock_irqsave(&contr->lock, flags); |
163 | if (!(irq_list[irq].flags & IRQ_FLG_STD)) { | 172 | |
164 | if (irq_list[irq].flags & IRQ_FLG_LOCK) { | 173 | prev = irq_list + irq; |
165 | printk("%s: IRQ %d from %s is not replaceable\n", | 174 | if (*prev) { |
166 | __FUNCTION__, irq, irq_list[irq].devname); | 175 | /* Can't share interrupts unless both agree to */ |
167 | return -EBUSY; | 176 | if (!((*prev)->flags & node->flags & SA_SHIRQ)) { |
168 | } | 177 | spin_unlock_irqrestore(&contr->lock, flags); |
169 | if (!(flags & IRQ_FLG_REPLACE)) { | ||
170 | printk("%s: %s can't replace IRQ %d from %s\n", | ||
171 | __FUNCTION__, devname, irq, irq_list[irq].devname); | ||
172 | return -EBUSY; | 178 | return -EBUSY; |
173 | } | 179 | } |
180 | while (*prev) | ||
181 | prev = &(*prev)->next; | ||
174 | } | 182 | } |
175 | #endif | ||
176 | 183 | ||
177 | irq_list[irq].handler = handler; | 184 | if (!irq_list[irq]) { |
178 | irq_list[irq].flags = flags; | 185 | if (contr->startup) |
179 | irq_list[irq].dev_id = dev_id; | 186 | contr->startup(irq); |
180 | irq_list[irq].devname = devname; | 187 | else |
188 | contr->enable(irq); | ||
189 | } | ||
190 | node->next = NULL; | ||
191 | *prev = node; | ||
192 | |||
193 | spin_unlock_irqrestore(&contr->lock, flags); | ||
194 | |||
181 | return 0; | 195 | return 0; |
182 | } | 196 | } |
183 | 197 | ||
198 | int cpu_request_irq(unsigned int irq, | ||
199 | irqreturn_t (*handler)(int, void *, struct pt_regs *), | ||
200 | unsigned long flags, const char *devname, void *dev_id) | ||
201 | { | ||
202 | struct irq_node *node; | ||
203 | int res; | ||
204 | |||
205 | node = new_irq_node(); | ||
206 | if (!node) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | node->handler = handler; | ||
210 | node->flags = flags; | ||
211 | node->dev_id = dev_id; | ||
212 | node->devname = devname; | ||
213 | |||
214 | res = setup_irq(irq, node); | ||
215 | if (res) | ||
216 | node->handler = NULL; | ||
217 | |||
218 | return res; | ||
219 | } | ||
220 | |||
184 | void cpu_free_irq(unsigned int irq, void *dev_id) | 221 | void cpu_free_irq(unsigned int irq, void *dev_id) |
185 | { | 222 | { |
186 | if (irq < IRQ_AUTO_1 || irq > IRQ_AUTO_7) { | 223 | struct irq_controller *contr; |
224 | struct irq_node **p, *node; | ||
225 | unsigned long flags; | ||
226 | |||
227 | if (irq >= SYS_IRQS || !(contr = irq_controller[irq])) { | ||
187 | printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); | 228 | printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); |
188 | return; | 229 | return; |
189 | } | 230 | } |
190 | 231 | ||
191 | if (irq_list[irq].dev_id != dev_id) | 232 | spin_lock_irqsave(&contr->lock, flags); |
192 | printk("%s: Removing probably wrong IRQ %d from %s\n", | 233 | |
193 | __FUNCTION__, irq, irq_list[irq].devname); | 234 | p = irq_list + irq; |
235 | while ((node = *p)) { | ||
236 | if (node->dev_id == dev_id) | ||
237 | break; | ||
238 | p = &node->next; | ||
239 | } | ||
240 | |||
241 | if (node) { | ||
242 | *p = node->next; | ||
243 | node->handler = NULL; | ||
244 | } else | ||
245 | printk("%s: Removing probably wrong IRQ %d\n", | ||
246 | __FUNCTION__, irq); | ||
247 | |||
248 | if (!irq_list[irq]) | ||
249 | contr->shutdown(irq); | ||
194 | 250 | ||
195 | irq_list[irq].handler = (*mach_default_handler)[irq]; | 251 | spin_unlock_irqrestore(&contr->lock, flags); |
196 | irq_list[irq].flags = 0; | ||
197 | irq_list[irq].dev_id = NULL; | ||
198 | irq_list[irq].devname = default_names[irq]; | ||
199 | } | 252 | } |
200 | 253 | ||
254 | int m68k_irq_startup(unsigned int irq) | ||
255 | { | ||
256 | if (irq <= IRQ_AUTO_7) | ||
257 | vectors[VEC_SPUR + irq] = auto_inthandler; | ||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | void m68k_irq_shutdown(unsigned int irq) | ||
262 | { | ||
263 | if (irq <= IRQ_AUTO_7) | ||
264 | vectors[VEC_SPUR + irq] = bad_inthandler; | ||
265 | } | ||
266 | |||
267 | |||
201 | /* | 268 | /* |
202 | * Do we need these probe functions on the m68k? | 269 | * Do we need these probe functions on the m68k? |
203 | * | 270 | * |
@@ -250,8 +317,14 @@ static void dummy_free_irq(unsigned int irq, void *dev_id) | |||
250 | 317 | ||
251 | asmlinkage void m68k_handle_int(unsigned int irq, struct pt_regs *regs) | 318 | asmlinkage void m68k_handle_int(unsigned int irq, struct pt_regs *regs) |
252 | { | 319 | { |
320 | struct irq_node *node; | ||
321 | |||
253 | kstat_cpu(0).irqs[irq]++; | 322 | kstat_cpu(0).irqs[irq]++; |
254 | irq_list[irq].handler(irq, irq_list[irq].dev_id, regs); | 323 | node = irq_list[irq]; |
324 | do { | ||
325 | node->handler(irq, node->dev_id, regs); | ||
326 | node = node->next; | ||
327 | } while (node); | ||
255 | } | 328 | } |
256 | 329 | ||
257 | asmlinkage void handle_badint(struct pt_regs *regs) | 330 | asmlinkage void handle_badint(struct pt_regs *regs) |
@@ -262,16 +335,18 @@ asmlinkage void handle_badint(struct pt_regs *regs) | |||
262 | 335 | ||
263 | int show_interrupts(struct seq_file *p, void *v) | 336 | int show_interrupts(struct seq_file *p, void *v) |
264 | { | 337 | { |
338 | struct irq_controller *contr; | ||
339 | struct irq_node *node; | ||
265 | int i = *(loff_t *) v; | 340 | int i = *(loff_t *) v; |
266 | 341 | ||
267 | /* autovector interrupts */ | 342 | /* autovector interrupts */ |
268 | if (i < SYS_IRQS) { | 343 | if (i < SYS_IRQS && irq_list[i]) { |
269 | if (mach_default_handler) { | 344 | contr = irq_controller[i]; |
270 | seq_printf(p, "auto %2d: %10u ", i, | 345 | node = irq_list[i]; |
271 | i ? kstat_cpu(0).irqs[i] : num_spurious); | 346 | seq_printf(p, "%s %u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname); |
272 | seq_puts(p, " "); | 347 | while ((node = node->next)) |
273 | seq_printf(p, "%s\n", irq_list[i].devname); | 348 | seq_printf(p, ", %s", node->devname); |
274 | } | 349 | seq_puts(p, "\n"); |
275 | } else if (i == SYS_IRQS) | 350 | } else if (i == SYS_IRQS) |
276 | mach_get_irq_list(p, v); | 351 | mach_get_irq_list(p, v); |
277 | return 0; | 352 | return 0; |
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index 19dce75711b1..7e04f2a695c0 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c | |||
@@ -94,20 +94,6 @@ static void mac_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *)) | |||
94 | via_init_clock(vector); | 94 | via_init_clock(vector); |
95 | } | 95 | } |
96 | 96 | ||
97 | extern irqreturn_t mac_default_handler(int, void *, struct pt_regs *); | ||
98 | |||
99 | irqreturn_t (*mac_handlers[8])(int, void *, struct pt_regs *)= | ||
100 | { | ||
101 | mac_default_handler, | ||
102 | mac_default_handler, | ||
103 | mac_default_handler, | ||
104 | mac_default_handler, | ||
105 | mac_default_handler, | ||
106 | mac_default_handler, | ||
107 | mac_default_handler, | ||
108 | mac_default_handler | ||
109 | }; | ||
110 | |||
111 | /* | 97 | /* |
112 | * Parse a Macintosh-specific record in the bootinfo | 98 | * Parse a Macintosh-specific record in the bootinfo |
113 | */ | 99 | */ |
@@ -188,7 +174,6 @@ void __init config_mac(void) | |||
188 | enable_irq = mac_enable_irq; | 174 | enable_irq = mac_enable_irq; |
189 | disable_irq = mac_disable_irq; | 175 | disable_irq = mac_disable_irq; |
190 | mach_get_model = mac_get_model; | 176 | mach_get_model = mac_get_model; |
191 | mach_default_handler = &mac_handlers; | ||
192 | mach_get_irq_list = show_mac_interrupts; | 177 | mach_get_irq_list = show_mac_interrupts; |
193 | mach_gettimeoffset = mac_gettimeoffset; | 178 | mach_gettimeoffset = mac_gettimeoffset; |
194 | #warning move to adb/via init | 179 | #warning move to adb/via init |
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index 7a1600bd195d..73b39cd3f94c 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c | |||
@@ -637,13 +637,6 @@ int show_mac_interrupts(struct seq_file *p, void *v) | |||
637 | return 0; | 637 | return 0; |
638 | } | 638 | } |
639 | 639 | ||
640 | void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs) | ||
641 | { | ||
642 | #ifdef DEBUG_SPURIOUS | ||
643 | printk("Unexpected IRQ %d on device %p\n", irq, dev_id); | ||
644 | #endif | ||
645 | } | ||
646 | |||
647 | static int num_debug[8]; | 640 | static int num_debug[8]; |
648 | 641 | ||
649 | irqreturn_t mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs) | 642 | irqreturn_t mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs) |
diff --git a/arch/m68k/mvme147/147ints.c b/arch/m68k/mvme147/147ints.c index 69a744ee35a3..b4aa5e8f44ea 100644 --- a/arch/m68k/mvme147/147ints.c +++ b/arch/m68k/mvme147/147ints.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/interrupt.h> | ||
17 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
18 | 19 | ||
19 | #include <asm/ptrace.h> | 20 | #include <asm/ptrace.h> |
diff --git a/arch/m68k/mvme16x/16xints.c b/arch/m68k/mvme16x/16xints.c index 793ef735b59c..81afada90dd2 100644 --- a/arch/m68k/mvme16x/16xints.c +++ b/arch/m68k/mvme16x/16xints.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/interrupt.h> | ||
17 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
18 | 19 | ||
19 | #include <asm/system.h> | 20 | #include <asm/system.h> |
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index 5e0f9b04d45e..01fd662bfada 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <asm/q40_master.h> | 37 | #include <asm/q40_master.h> |
38 | 38 | ||
39 | extern irqreturn_t q40_process_int (int level, struct pt_regs *regs); | 39 | extern irqreturn_t q40_process_int (int level, struct pt_regs *regs); |
40 | extern irqreturn_t (*q40_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */ | ||
41 | extern void q40_init_IRQ (void); | 40 | extern void q40_init_IRQ (void); |
42 | extern void q40_free_irq (unsigned int, void *); | 41 | extern void q40_free_irq (unsigned int, void *); |
43 | extern int show_q40_interrupts (struct seq_file *, void *); | 42 | extern int show_q40_interrupts (struct seq_file *, void *); |
@@ -181,7 +180,6 @@ void __init config_q40(void) | |||
181 | mach_request_irq = q40_request_irq; | 180 | mach_request_irq = q40_request_irq; |
182 | enable_irq = q40_enable_irq; | 181 | enable_irq = q40_enable_irq; |
183 | disable_irq = q40_disable_irq; | 182 | disable_irq = q40_disable_irq; |
184 | mach_default_handler = &q40_default_handler; | ||
185 | mach_get_model = q40_get_model; | 183 | mach_get_model = q40_get_model; |
186 | mach_get_hardware_list = q40_get_hardware_list; | 184 | mach_get_hardware_list = q40_get_hardware_list; |
187 | 185 | ||
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c index b106839ad813..ff80cba110d4 100644 --- a/arch/m68k/q40/q40ints.c +++ b/arch/m68k/q40/q40ints.c | |||
@@ -46,7 +46,6 @@ irqreturn_t q40_irq2_handler (int, void *, struct pt_regs *fp); | |||
46 | 46 | ||
47 | 47 | ||
48 | static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp); | 48 | static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp); |
49 | static irqreturn_t default_handler(int lev, void *dev_id, struct pt_regs *regs); | ||
50 | 49 | ||
51 | 50 | ||
52 | #define DEVNAME_SIZE 24 | 51 | #define DEVNAME_SIZE 24 |
@@ -415,22 +414,6 @@ static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp) | |||
415 | else master_outb(-1,KEYBOARD_UNLOCK_REG); | 414 | else master_outb(-1,KEYBOARD_UNLOCK_REG); |
416 | return IRQ_NONE; | 415 | return IRQ_NONE; |
417 | } | 416 | } |
418 | static irqreturn_t default_handler(int lev, void *dev_id, struct pt_regs *regs) | ||
419 | { | ||
420 | printk ("Uninitialised interrupt level %d\n", lev); | ||
421 | return IRQ_NONE; | ||
422 | } | ||
423 | |||
424 | irqreturn_t (*q40_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { | ||
425 | [0] = default_handler, | ||
426 | [1] = default_handler, | ||
427 | [2] = default_handler, | ||
428 | [3] = default_handler, | ||
429 | [4] = default_handler, | ||
430 | [5] = default_handler, | ||
431 | [6] = default_handler, | ||
432 | [7] = default_handler | ||
433 | }; | ||
434 | 417 | ||
435 | 418 | ||
436 | void q40_enable_irq (unsigned int irq) | 419 | void q40_enable_irq (unsigned int irq) |