diff options
-rw-r--r-- | arch/m68k/kernel/entry.S | 11 | ||||
-rw-r--r-- | arch/m68k/kernel/ints.c | 240 | ||||
-rw-r--r-- | arch/m68k/kernel/m68k_ksyms.c | 2 | ||||
-rw-r--r-- | arch/m68k/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/m68k/kernel/traps.c | 7 | ||||
-rw-r--r-- | include/asm-m68k/irq.h | 65 | ||||
-rw-r--r-- | include/asm-m68k/machdep.h | 6 | ||||
-rw-r--r-- | include/asm-m68k/traps.h | 2 |
8 files changed, 188 insertions, 148 deletions
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 1fb88f3311de..48cccc556e13 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S | |||
@@ -48,6 +48,8 @@ | |||
48 | .globl sys_call_table | 48 | .globl sys_call_table |
49 | .globl sys_fork, sys_clone, sys_vfork | 49 | .globl sys_fork, sys_clone, sys_vfork |
50 | .globl ret_from_interrupt, bad_interrupt | 50 | .globl ret_from_interrupt, bad_interrupt |
51 | .globl auto_irqhandler_fixup | ||
52 | .globl user_irqvec_fixup, user_irqhandler_fixup | ||
51 | 53 | ||
52 | .text | 54 | .text |
53 | ENTRY(buserr) | 55 | ENTRY(buserr) |
@@ -212,6 +214,7 @@ ENTRY(auto_inthandler) | |||
212 | jbra 3f | 214 | jbra 3f |
213 | 1: | 215 | 1: |
214 | #endif | 216 | #endif |
217 | auto_irqhandler_fixup = . + 2 | ||
215 | jsr m68k_handle_int | process the IRQ | 218 | jsr m68k_handle_int | process the IRQ |
216 | 3: addql #8,%sp | pop parameters off stack | 219 | 3: addql #8,%sp | pop parameters off stack |
217 | 220 | ||
@@ -234,17 +237,19 @@ ret_from_last_interrupt: | |||
234 | 237 | ||
235 | /* Handler for user defined interrupt vectors */ | 238 | /* Handler for user defined interrupt vectors */ |
236 | 239 | ||
237 | ENTRY(mach_inthandler) | 240 | ENTRY(user_inthandler) |
238 | SAVE_ALL_INT | 241 | SAVE_ALL_INT |
239 | GET_CURRENT(%d0) | 242 | GET_CURRENT(%d0) |
240 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | 243 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) |
241 | | put exception # in d0 | 244 | | put exception # in d0 |
242 | bfextu %sp@(PT_VECTOR){#4,#10},%d0 | 245 | bfextu %sp@(PT_VECTOR){#4,#10},%d0 |
246 | user_irqvec_fixup = . + 2 | ||
247 | subw #VEC_USER,%d0 | ||
243 | 248 | ||
244 | movel %sp,%sp@- | 249 | movel %sp,%sp@- |
245 | movel %d0,%sp@- | put vector # on stack | 250 | movel %d0,%sp@- | put vector # on stack |
246 | movel mach_process_int,%a0 | 251 | user_irqhandler_fixup = . + 2 |
247 | jsr %a0@ | process the IRQ | 252 | jsr m68k_handle_int | process the IRQ |
248 | addql #8,%sp | pop parameters off stack | 253 | addql #8,%sp | pop parameters off stack |
249 | 254 | ||
250 | subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | 255 | subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) |
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index c7f6ee67fd5a..5a8344b93547 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c | |||
@@ -39,14 +39,22 @@ | |||
39 | #include <asm/traps.h> | 39 | #include <asm/traps.h> |
40 | #include <asm/page.h> | 40 | #include <asm/page.h> |
41 | #include <asm/machdep.h> | 41 | #include <asm/machdep.h> |
42 | #include <asm/cacheflush.h> | ||
42 | 43 | ||
43 | #ifdef CONFIG_Q40 | 44 | #ifdef CONFIG_Q40 |
44 | #include <asm/q40ints.h> | 45 | #include <asm/q40ints.h> |
45 | #endif | 46 | #endif |
46 | 47 | ||
48 | extern u32 auto_irqhandler_fixup[]; | ||
49 | extern u32 user_irqhandler_fixup[]; | ||
50 | extern u16 user_irqvec_fixup[]; | ||
51 | |||
47 | /* table for system interrupt handlers */ | 52 | /* table for system interrupt handlers */ |
48 | static struct irq_node *irq_list[SYS_IRQS]; | 53 | static struct irq_node *irq_list[NR_IRQS]; |
49 | static struct irq_controller *irq_controller[SYS_IRQS]; | 54 | static struct irq_controller *irq_controller[NR_IRQS]; |
55 | static int irq_depth[NR_IRQS]; | ||
56 | |||
57 | static int m68k_first_user_vec; | ||
50 | 58 | ||
51 | static struct irq_controller auto_irq_controller = { | 59 | static struct irq_controller auto_irq_controller = { |
52 | .name = "auto", | 60 | .name = "auto", |
@@ -55,39 +63,16 @@ static struct irq_controller auto_irq_controller = { | |||
55 | .shutdown = m68k_irq_shutdown, | 63 | .shutdown = m68k_irq_shutdown, |
56 | }; | 64 | }; |
57 | 65 | ||
58 | static const char *default_names[SYS_IRQS] = { | 66 | static struct irq_controller user_irq_controller = { |
59 | [0] = "spurious int", | 67 | .name = "user", |
60 | [1] = "int1 handler", | 68 | .lock = SPIN_LOCK_UNLOCKED, |
61 | [2] = "int2 handler", | 69 | .startup = m68k_irq_startup, |
62 | [3] = "int3 handler", | 70 | .shutdown = m68k_irq_shutdown, |
63 | [4] = "int4 handler", | ||
64 | [5] = "int5 handler", | ||
65 | [6] = "int6 handler", | ||
66 | [7] = "int7 handler" | ||
67 | }; | 71 | }; |
68 | 72 | ||
69 | /* The number of spurious interrupts */ | ||
70 | volatile unsigned int num_spurious; | ||
71 | |||
72 | #define NUM_IRQ_NODES 100 | 73 | #define NUM_IRQ_NODES 100 |
73 | static irq_node_t nodes[NUM_IRQ_NODES]; | 74 | static irq_node_t nodes[NUM_IRQ_NODES]; |
74 | 75 | ||
75 | static void dummy_enable_irq(unsigned int irq); | ||
76 | static void dummy_disable_irq(unsigned int irq); | ||
77 | static int dummy_request_irq(unsigned int irq, | ||
78 | irqreturn_t (*handler) (int, void *, struct pt_regs *), | ||
79 | unsigned long flags, const char *devname, void *dev_id); | ||
80 | static void dummy_free_irq(unsigned int irq, void *dev_id); | ||
81 | |||
82 | void (*enable_irq) (unsigned int) = dummy_enable_irq; | ||
83 | void (*disable_irq) (unsigned int) = dummy_disable_irq; | ||
84 | |||
85 | int (*mach_request_irq) (unsigned int, irqreturn_t (*)(int, void *, struct pt_regs *), | ||
86 | unsigned long, const char *, void *) = dummy_request_irq; | ||
87 | void (*mach_free_irq) (unsigned int, void *) = dummy_free_irq; | ||
88 | |||
89 | void init_irq_proc(void); | ||
90 | |||
91 | /* | 76 | /* |
92 | * void init_IRQ(void) | 77 | * void init_IRQ(void) |
93 | * | 78 | * |
@@ -109,14 +94,70 @@ void __init init_IRQ(void) | |||
109 | hardirq_mask_is_broken(); | 94 | hardirq_mask_is_broken(); |
110 | } | 95 | } |
111 | 96 | ||
112 | for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) { | 97 | for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) |
113 | irq_controller[i] = &auto_irq_controller; | 98 | irq_controller[i] = &auto_irq_controller; |
114 | if (mach_default_handler && (*mach_default_handler)[i]) | ||
115 | cpu_request_irq(i, (*mach_default_handler)[i], | ||
116 | 0, default_names[i], NULL); | ||
117 | } | ||
118 | 99 | ||
119 | mach_init_IRQ (); | 100 | mach_init_IRQ(); |
101 | } | ||
102 | |||
103 | /** | ||
104 | * m68k_setup_auto_interrupt | ||
105 | * @handler: called from auto vector interrupts | ||
106 | * | ||
107 | * setup the handler to be called from auto vector interrupts instead of the | ||
108 | * standard m68k_handle_int(), it will be called with irq numbers in the range | ||
109 | * from IRQ_AUTO_1 - IRQ_AUTO_7. | ||
110 | */ | ||
111 | void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)) | ||
112 | { | ||
113 | if (handler) | ||
114 | *auto_irqhandler_fixup = (u32)handler; | ||
115 | flush_icache(); | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * m68k_setup_user_interrupt | ||
120 | * @vec: first user vector interrupt to handle | ||
121 | * @cnt: number of active user vector interrupts | ||
122 | * @handler: called from user vector interrupts | ||
123 | * | ||
124 | * setup user vector interrupts, this includes activating the specified range | ||
125 | * of interrupts, only then these interrupts can be requested (note: this is | ||
126 | * different from auto vector interrupts). An optional handler can be installed | ||
127 | * to be called instead of the default m68k_handle_int(), it will be called | ||
128 | * with irq numbers starting from IRQ_USER. | ||
129 | */ | ||
130 | void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, | ||
131 | void (*handler)(unsigned int, struct pt_regs *)) | ||
132 | { | ||
133 | int i; | ||
134 | |||
135 | m68k_first_user_vec = vec; | ||
136 | for (i = 0; i < cnt; i++) | ||
137 | irq_controller[IRQ_USER + i] = &user_irq_controller; | ||
138 | *user_irqvec_fixup = vec - IRQ_USER; | ||
139 | if (handler) | ||
140 | *user_irqhandler_fixup = (u32)handler; | ||
141 | flush_icache(); | ||
142 | } | ||
143 | |||
144 | /** | ||
145 | * m68k_setup_irq_controller | ||
146 | * @contr: irq controller which controls specified irq | ||
147 | * @irq: first irq to be managed by the controller | ||
148 | * | ||
149 | * Change the controller for the specified range of irq, which will be used to | ||
150 | * manage these irq. auto/user irq already have a default controller, which can | ||
151 | * be changed as well, but the controller probably should use m68k_irq_startup/ | ||
152 | * m68k_irq_shutdown. | ||
153 | */ | ||
154 | void m68k_setup_irq_controller(struct irq_controller *contr, unsigned int irq, | ||
155 | unsigned int cnt) | ||
156 | { | ||
157 | int i; | ||
158 | |||
159 | for (i = 0; i < cnt; i++) | ||
160 | irq_controller[irq + i] = contr; | ||
120 | } | 161 | } |
121 | 162 | ||
122 | irq_node_t *new_irq_node(void) | 163 | irq_node_t *new_irq_node(void) |
@@ -135,34 +176,13 @@ irq_node_t *new_irq_node(void) | |||
135 | return NULL; | 176 | return NULL; |
136 | } | 177 | } |
137 | 178 | ||
138 | /* | ||
139 | * We will keep these functions until I have convinced Linus to move | ||
140 | * the declaration of them from include/linux/sched.h to | ||
141 | * include/asm/irq.h. | ||
142 | */ | ||
143 | int request_irq(unsigned int irq, | ||
144 | irqreturn_t (*handler) (int, void *, struct pt_regs *), | ||
145 | unsigned long flags, const char *devname, void *dev_id) | ||
146 | { | ||
147 | return mach_request_irq(irq, handler, flags, devname, dev_id); | ||
148 | } | ||
149 | |||
150 | EXPORT_SYMBOL(request_irq); | ||
151 | |||
152 | void free_irq(unsigned int irq, void *dev_id) | ||
153 | { | ||
154 | mach_free_irq(irq, dev_id); | ||
155 | } | ||
156 | |||
157 | EXPORT_SYMBOL(free_irq); | ||
158 | |||
159 | int setup_irq(unsigned int irq, struct irq_node *node) | 179 | int setup_irq(unsigned int irq, struct irq_node *node) |
160 | { | 180 | { |
161 | struct irq_controller *contr; | 181 | struct irq_controller *contr; |
162 | struct irq_node **prev; | 182 | struct irq_node **prev; |
163 | unsigned long flags; | 183 | unsigned long flags; |
164 | 184 | ||
165 | if (irq >= SYS_IRQS || !(contr = irq_controller[irq])) { | 185 | if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { |
166 | printk("%s: Incorrect IRQ %d from %s\n", | 186 | printk("%s: Incorrect IRQ %d from %s\n", |
167 | __FUNCTION__, irq, node->devname); | 187 | __FUNCTION__, irq, node->devname); |
168 | return -ENXIO; | 188 | return -ENXIO; |
@@ -195,9 +215,9 @@ int setup_irq(unsigned int irq, struct irq_node *node) | |||
195 | return 0; | 215 | return 0; |
196 | } | 216 | } |
197 | 217 | ||
198 | int cpu_request_irq(unsigned int irq, | 218 | int request_irq(unsigned int irq, |
199 | irqreturn_t (*handler)(int, void *, struct pt_regs *), | 219 | irqreturn_t (*handler) (int, void *, struct pt_regs *), |
200 | unsigned long flags, const char *devname, void *dev_id) | 220 | unsigned long flags, const char *devname, void *dev_id) |
201 | { | 221 | { |
202 | struct irq_node *node; | 222 | struct irq_node *node; |
203 | int res; | 223 | int res; |
@@ -218,13 +238,15 @@ int cpu_request_irq(unsigned int irq, | |||
218 | return res; | 238 | return res; |
219 | } | 239 | } |
220 | 240 | ||
221 | void cpu_free_irq(unsigned int irq, void *dev_id) | 241 | EXPORT_SYMBOL(request_irq); |
242 | |||
243 | void free_irq(unsigned int irq, void *dev_id) | ||
222 | { | 244 | { |
223 | struct irq_controller *contr; | 245 | struct irq_controller *contr; |
224 | struct irq_node **p, *node; | 246 | struct irq_node **p, *node; |
225 | unsigned long flags; | 247 | unsigned long flags; |
226 | 248 | ||
227 | if (irq >= SYS_IRQS || !(contr = irq_controller[irq])) { | 249 | if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { |
228 | printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); | 250 | printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); |
229 | return; | 251 | return; |
230 | } | 252 | } |
@@ -245,16 +267,69 @@ void cpu_free_irq(unsigned int irq, void *dev_id) | |||
245 | printk("%s: Removing probably wrong IRQ %d\n", | 267 | printk("%s: Removing probably wrong IRQ %d\n", |
246 | __FUNCTION__, irq); | 268 | __FUNCTION__, irq); |
247 | 269 | ||
248 | if (!irq_list[irq]) | 270 | if (!irq_list[irq]) { |
249 | contr->shutdown(irq); | 271 | if (contr->shutdown) |
272 | contr->shutdown(irq); | ||
273 | else | ||
274 | contr->disable(irq); | ||
275 | } | ||
276 | |||
277 | spin_unlock_irqrestore(&contr->lock, flags); | ||
278 | } | ||
279 | |||
280 | EXPORT_SYMBOL(free_irq); | ||
281 | |||
282 | void enable_irq(unsigned int irq) | ||
283 | { | ||
284 | struct irq_controller *contr; | ||
285 | unsigned long flags; | ||
286 | |||
287 | if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { | ||
288 | printk("%s: Incorrect IRQ %d\n", | ||
289 | __FUNCTION__, irq); | ||
290 | return; | ||
291 | } | ||
292 | |||
293 | spin_lock_irqsave(&contr->lock, flags); | ||
294 | if (irq_depth[irq]) { | ||
295 | if (!--irq_depth[irq]) { | ||
296 | if (contr->enable) | ||
297 | contr->enable(irq); | ||
298 | } | ||
299 | } else | ||
300 | WARN_ON(1); | ||
301 | spin_unlock_irqrestore(&contr->lock, flags); | ||
302 | } | ||
303 | |||
304 | EXPORT_SYMBOL(enable_irq); | ||
250 | 305 | ||
306 | void disable_irq(unsigned int irq) | ||
307 | { | ||
308 | struct irq_controller *contr; | ||
309 | unsigned long flags; | ||
310 | |||
311 | if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { | ||
312 | printk("%s: Incorrect IRQ %d\n", | ||
313 | __FUNCTION__, irq); | ||
314 | return; | ||
315 | } | ||
316 | |||
317 | spin_lock_irqsave(&contr->lock, flags); | ||
318 | if (!irq_depth[irq]++) { | ||
319 | if (contr->disable) | ||
320 | contr->disable(irq); | ||
321 | } | ||
251 | spin_unlock_irqrestore(&contr->lock, flags); | 322 | spin_unlock_irqrestore(&contr->lock, flags); |
252 | } | 323 | } |
253 | 324 | ||
325 | EXPORT_SYMBOL(disable_irq); | ||
326 | |||
254 | int m68k_irq_startup(unsigned int irq) | 327 | int m68k_irq_startup(unsigned int irq) |
255 | { | 328 | { |
256 | if (irq <= IRQ_AUTO_7) | 329 | if (irq <= IRQ_AUTO_7) |
257 | vectors[VEC_SPUR + irq] = auto_inthandler; | 330 | vectors[VEC_SPUR + irq] = auto_inthandler; |
331 | else | ||
332 | vectors[m68k_first_user_vec + irq - IRQ_USER] = user_inthandler; | ||
258 | return 0; | 333 | return 0; |
259 | } | 334 | } |
260 | 335 | ||
@@ -262,6 +337,8 @@ void m68k_irq_shutdown(unsigned int irq) | |||
262 | { | 337 | { |
263 | if (irq <= IRQ_AUTO_7) | 338 | if (irq <= IRQ_AUTO_7) |
264 | vectors[VEC_SPUR + irq] = bad_inthandler; | 339 | vectors[VEC_SPUR + irq] = bad_inthandler; |
340 | else | ||
341 | vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler; | ||
265 | } | 342 | } |
266 | 343 | ||
267 | 344 | ||
@@ -292,28 +369,16 @@ int probe_irq_off (unsigned long irqs) | |||
292 | 369 | ||
293 | EXPORT_SYMBOL(probe_irq_off); | 370 | EXPORT_SYMBOL(probe_irq_off); |
294 | 371 | ||
295 | static void dummy_enable_irq(unsigned int irq) | 372 | unsigned int irq_canonicalize(unsigned int irq) |
296 | { | 373 | { |
297 | printk("calling uninitialized enable_irq()\n"); | 374 | #ifdef CONFIG_Q40 |
298 | } | 375 | if (MACH_IS_Q40 && irq == 11) |
299 | 376 | irq = 10; | |
300 | static void dummy_disable_irq(unsigned int irq) | 377 | #endif |
301 | { | 378 | return irq; |
302 | printk("calling uninitialized disable_irq()\n"); | ||
303 | } | ||
304 | |||
305 | static int dummy_request_irq(unsigned int irq, | ||
306 | irqreturn_t (*handler) (int, void *, struct pt_regs *), | ||
307 | unsigned long flags, const char *devname, void *dev_id) | ||
308 | { | ||
309 | printk("calling uninitialized request_irq()\n"); | ||
310 | return 0; | ||
311 | } | 379 | } |
312 | 380 | ||
313 | static void dummy_free_irq(unsigned int irq, void *dev_id) | 381 | EXPORT_SYMBOL(irq_canonicalize); |
314 | { | ||
315 | printk("calling uninitialized disable_irq()\n"); | ||
316 | } | ||
317 | 382 | ||
318 | asmlinkage void m68k_handle_int(unsigned int irq, struct pt_regs *regs) | 383 | asmlinkage void m68k_handle_int(unsigned int irq, struct pt_regs *regs) |
319 | { | 384 | { |
@@ -340,15 +405,14 @@ int show_interrupts(struct seq_file *p, void *v) | |||
340 | int i = *(loff_t *) v; | 405 | int i = *(loff_t *) v; |
341 | 406 | ||
342 | /* autovector interrupts */ | 407 | /* autovector interrupts */ |
343 | if (i < SYS_IRQS && irq_list[i]) { | 408 | if (irq_list[i]) { |
344 | contr = irq_controller[i]; | 409 | contr = irq_controller[i]; |
345 | node = irq_list[i]; | 410 | node = irq_list[i]; |
346 | seq_printf(p, "%s %u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname); | 411 | seq_printf(p, "%-8s %3u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname); |
347 | while ((node = node->next)) | 412 | while ((node = node->next)) |
348 | seq_printf(p, ", %s", node->devname); | 413 | seq_printf(p, ", %s", node->devname); |
349 | seq_puts(p, "\n"); | 414 | seq_puts(p, "\n"); |
350 | } else if (i == SYS_IRQS) | 415 | } |
351 | mach_get_irq_list(p, v); | ||
352 | return 0; | 416 | return 0; |
353 | } | 417 | } |
354 | 418 | ||
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c index 5b7952ea2bae..1f5e1b5aeda4 100644 --- a/arch/m68k/kernel/m68k_ksyms.c +++ b/arch/m68k/kernel/m68k_ksyms.c | |||
@@ -57,8 +57,6 @@ EXPORT_SYMBOL(dump_thread); | |||
57 | EXPORT_SYMBOL(strnlen); | 57 | EXPORT_SYMBOL(strnlen); |
58 | EXPORT_SYMBOL(strrchr); | 58 | EXPORT_SYMBOL(strrchr); |
59 | EXPORT_SYMBOL(strstr); | 59 | EXPORT_SYMBOL(strstr); |
60 | EXPORT_SYMBOL(enable_irq); | ||
61 | EXPORT_SYMBOL(disable_irq); | ||
62 | EXPORT_SYMBOL(kernel_thread); | 60 | EXPORT_SYMBOL(kernel_thread); |
63 | #ifdef CONFIG_VME | 61 | #ifdef CONFIG_VME |
64 | EXPORT_SYMBOL(vme_brdtype); | 62 | EXPORT_SYMBOL(vme_brdtype); |
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 750d5b3c971f..214a95f9f3ac 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c | |||
@@ -68,11 +68,8 @@ char m68k_debug_device[6] = ""; | |||
68 | void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)) __initdata = NULL; | 68 | void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)) __initdata = NULL; |
69 | /* machine dependent irq functions */ | 69 | /* machine dependent irq functions */ |
70 | void (*mach_init_IRQ) (void) __initdata = NULL; | 70 | void (*mach_init_IRQ) (void) __initdata = NULL; |
71 | irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); | ||
72 | void (*mach_get_model) (char *model); | 71 | void (*mach_get_model) (char *model); |
73 | int (*mach_get_hardware_list) (char *buffer); | 72 | int (*mach_get_hardware_list) (char *buffer); |
74 | int (*mach_get_irq_list) (struct seq_file *, void *); | ||
75 | irqreturn_t (*mach_process_int) (int, struct pt_regs *); | ||
76 | /* machine dependent timer functions */ | 73 | /* machine dependent timer functions */ |
77 | unsigned long (*mach_gettimeoffset) (void); | 74 | unsigned long (*mach_gettimeoffset) (void); |
78 | int (*mach_hwclk) (int, struct rtc_time*); | 75 | int (*mach_hwclk) (int, struct rtc_time*); |
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index b19b951fd3e7..e86de7b061cd 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c | |||
@@ -87,16 +87,15 @@ void __init trap_init (void) | |||
87 | { | 87 | { |
88 | int i; | 88 | int i; |
89 | 89 | ||
90 | vectors[VEC_SPUR] = bad_inthandler; | 90 | for (i = VEC_SPUR; i <= VEC_INT7; i++) |
91 | for (i = VEC_INT1; i <= VEC_INT7; i++) | 91 | vectors[i] = bad_inthandler; |
92 | vectors[i] = auto_inthandler; | ||
93 | 92 | ||
94 | for (i = 0; i < VEC_USER; i++) | 93 | for (i = 0; i < VEC_USER; i++) |
95 | if (!vectors[i]) | 94 | if (!vectors[i]) |
96 | vectors[i] = trap; | 95 | vectors[i] = trap; |
97 | 96 | ||
98 | for (i = VEC_USER; i < 256; i++) | 97 | for (i = VEC_USER; i < 256; i++) |
99 | vectors[i] = mach_inthandler; | 98 | vectors[i] = bad_inthandler; |
100 | 99 | ||
101 | #ifdef CONFIG_M68KFPU_EMU | 100 | #ifdef CONFIG_M68KFPU_EMU |
102 | if (FPU_IS_EMU) | 101 | if (FPU_IS_EMU) |
diff --git a/include/asm-m68k/irq.h b/include/asm-m68k/irq.h index 7fa8733bb4cc..f4ae7d8feac6 100644 --- a/include/asm-m68k/irq.h +++ b/include/asm-m68k/irq.h | |||
@@ -1,25 +1,30 @@ | |||
1 | #ifndef _M68K_IRQ_H_ | 1 | #ifndef _M68K_IRQ_H_ |
2 | #define _M68K_IRQ_H_ | 2 | #define _M68K_IRQ_H_ |
3 | 3 | ||
4 | #include <linux/linkage.h> | ||
4 | #include <linux/hardirq.h> | 5 | #include <linux/hardirq.h> |
5 | #include <linux/spinlock_types.h> | 6 | #include <linux/spinlock_types.h> |
6 | 7 | ||
7 | /* | 8 | /* |
8 | * # of m68k auto vector interrupts | ||
9 | */ | ||
10 | |||
11 | #define SYS_IRQS 8 | ||
12 | |||
13 | /* | ||
14 | * This should be the same as the max(NUM_X_SOURCES) for all the | 9 | * This should be the same as the max(NUM_X_SOURCES) for all the |
15 | * different m68k hosts compiled into the kernel. | 10 | * different m68k hosts compiled into the kernel. |
16 | * Currently the Atari has 72 and the Amiga 24, but if both are | 11 | * Currently the Atari has 72 and the Amiga 24, but if both are |
17 | * supported in the kernel it is better to make room for 72. | 12 | * supported in the kernel it is better to make room for 72. |
18 | */ | 13 | */ |
19 | #if defined(CONFIG_ATARI) || defined(CONFIG_MAC) | 14 | #if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) |
20 | #define NR_IRQS (72+SYS_IRQS) | 15 | #define NR_IRQS 200 |
16 | #elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) | ||
17 | #define NR_IRQS 72 | ||
18 | #elif defined(CONFIG_Q40) | ||
19 | #define NR_IRQS 43 | ||
20 | #elif defined(CONFIG_AMIGA) | ||
21 | #define NR_IRQS 32 | ||
22 | #elif defined(CONFIG_APOLLO) | ||
23 | #define NR_IRQS 24 | ||
24 | #elif defined(CONFIG_HP300) | ||
25 | #define NR_IRQS 8 | ||
21 | #else | 26 | #else |
22 | #define NR_IRQS (24+SYS_IRQS) | 27 | #error unknown nr of irqs |
23 | #endif | 28 | #endif |
24 | 29 | ||
25 | /* | 30 | /* |
@@ -53,39 +58,13 @@ | |||
53 | 58 | ||
54 | #define IRQ_USER 8 | 59 | #define IRQ_USER 8 |
55 | 60 | ||
56 | static __inline__ int irq_canonicalize(int irq) | 61 | extern unsigned int irq_canonicalize(unsigned int irq); |
57 | { | 62 | extern void enable_irq(unsigned int); |
58 | return irq; | 63 | extern void disable_irq(unsigned int); |
59 | } | ||
60 | |||
61 | /* | ||
62 | * Machine specific interrupt sources. | ||
63 | * | ||
64 | * Adding an interrupt service routine for a source with this bit | ||
65 | * set indicates a special machine specific interrupt source. | ||
66 | * The machine specific files define these sources. | ||
67 | * | ||
68 | * The IRQ_MACHSPEC bit is now gone - the only thing it did was to | ||
69 | * introduce unnecessary overhead. | ||
70 | * | ||
71 | * All interrupt handling is actually machine specific so it is better | ||
72 | * to use function pointers, as used by the Sparc port, and select the | ||
73 | * interrupt handling functions when initializing the kernel. This way | ||
74 | * we save some unnecessary overhead at run-time. | ||
75 | * 01/11/97 - Jes | ||
76 | */ | ||
77 | |||
78 | extern void (*enable_irq)(unsigned int); | ||
79 | extern void (*disable_irq)(unsigned int); | ||
80 | #define disable_irq_nosync disable_irq | 64 | #define disable_irq_nosync disable_irq |
81 | 65 | ||
82 | struct pt_regs; | 66 | struct pt_regs; |
83 | 67 | ||
84 | extern int cpu_request_irq(unsigned int, | ||
85 | int (*)(int, void *, struct pt_regs *), | ||
86 | unsigned long, const char *, void *); | ||
87 | extern void cpu_free_irq(unsigned int, void *); | ||
88 | |||
89 | /* | 68 | /* |
90 | * various flags for request_irq() - the Amiga now uses the standard | 69 | * various flags for request_irq() - the Amiga now uses the standard |
91 | * mechanism like all other architectures - SA_INTERRUPT and SA_SHIRQ | 70 | * mechanism like all other architectures - SA_INTERRUPT and SA_SHIRQ |
@@ -133,12 +112,16 @@ struct irq_controller { | |||
133 | extern int m68k_irq_startup(unsigned int); | 112 | extern int m68k_irq_startup(unsigned int); |
134 | extern void m68k_irq_shutdown(unsigned int); | 113 | extern void m68k_irq_shutdown(unsigned int); |
135 | 114 | ||
136 | /* count of spurious interrupts */ | ||
137 | extern volatile unsigned int num_spurious; | ||
138 | |||
139 | /* | 115 | /* |
140 | * This function returns a new irq_node_t | 116 | * This function returns a new irq_node_t |
141 | */ | 117 | */ |
142 | extern irq_node_t *new_irq_node(void); | 118 | extern irq_node_t *new_irq_node(void); |
143 | 119 | ||
120 | extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); | ||
121 | extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, | ||
122 | void (*handler)(unsigned int, struct pt_regs *)); | ||
123 | extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); | ||
124 | |||
125 | asmlinkage void m68k_handle_int(unsigned int, struct pt_regs *); | ||
126 | |||
144 | #endif /* _M68K_IRQ_H_ */ | 127 | #endif /* _M68K_IRQ_H_ */ |
diff --git a/include/asm-m68k/machdep.h b/include/asm-m68k/machdep.h index 7d3fee342369..df898f27e434 100644 --- a/include/asm-m68k/machdep.h +++ b/include/asm-m68k/machdep.h | |||
@@ -13,14 +13,8 @@ struct buffer_head; | |||
13 | extern void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)); | 13 | extern void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)); |
14 | /* machine dependent irq functions */ | 14 | /* machine dependent irq functions */ |
15 | extern void (*mach_init_IRQ) (void); | 15 | extern void (*mach_init_IRQ) (void); |
16 | extern irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); | ||
17 | extern int (*mach_request_irq) (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), | ||
18 | unsigned long flags, const char *devname, void *dev_id); | ||
19 | extern void (*mach_free_irq) (unsigned int irq, void *dev_id); | ||
20 | extern void (*mach_get_model) (char *model); | 16 | extern void (*mach_get_model) (char *model); |
21 | extern int (*mach_get_hardware_list) (char *buffer); | 17 | extern int (*mach_get_hardware_list) (char *buffer); |
22 | extern int (*mach_get_irq_list) (struct seq_file *p, void *v); | ||
23 | extern irqreturn_t (*mach_process_int) (int irq, struct pt_regs *fp); | ||
24 | /* machine dependent timer functions */ | 18 | /* machine dependent timer functions */ |
25 | extern unsigned long (*mach_gettimeoffset)(void); | 19 | extern unsigned long (*mach_gettimeoffset)(void); |
26 | extern int (*mach_hwclk)(int, struct rtc_time*); | 20 | extern int (*mach_hwclk)(int, struct rtc_time*); |
diff --git a/include/asm-m68k/traps.h b/include/asm-m68k/traps.h index 771519473285..8caef25624c7 100644 --- a/include/asm-m68k/traps.h +++ b/include/asm-m68k/traps.h | |||
@@ -19,7 +19,7 @@ | |||
19 | typedef void (*e_vector)(void); | 19 | typedef void (*e_vector)(void); |
20 | 20 | ||
21 | asmlinkage void auto_inthandler(void); | 21 | asmlinkage void auto_inthandler(void); |
22 | asmlinkage void mach_inthandler(void); | 22 | asmlinkage void user_inthandler(void); |
23 | asmlinkage void bad_inthandler(void); | 23 | asmlinkage void bad_inthandler(void); |
24 | 24 | ||
25 | extern e_vector vectors[]; | 25 | extern e_vector vectors[]; |