diff options
author | Greg Ungerer <gerg@snapgear.com> | 2007-07-19 04:49:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-19 13:04:50 -0400 |
commit | 2502b667ea835ee16685c74b2a0d89ba8afe117a (patch) | |
tree | 31d492fb934df6d83819b679f3aa8d7f6952396d /arch/m68knommu | |
parent | f8af0bb890d6cdcb09ec042c128e217a7c500355 (diff) |
m68knommu: generic irq handling
Change the m68knommu irq handling to use the generic irq framework.
Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/m68knommu')
-rw-r--r-- | arch/m68knommu/Kconfig | 4 | ||||
-rw-r--r-- | arch/m68knommu/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/m68knommu/kernel/asm-offsets.c | 5 | ||||
-rw-r--r-- | arch/m68knommu/kernel/irq.c | 82 | ||||
-rw-r--r-- | arch/m68knommu/kernel/traps.c | 2 | ||||
-rw-r--r-- | arch/m68knommu/platform/5307/Makefile | 2 | ||||
-rw-r--r-- | arch/m68knommu/platform/5307/entry.S | 42 | ||||
-rw-r--r-- | arch/m68knommu/platform/5307/ints.c | 279 | ||||
-rw-r--r-- | arch/m68knommu/platform/5307/vectors.c | 29 | ||||
-rw-r--r-- | arch/m68knommu/platform/68328/entry.S | 10 | ||||
-rw-r--r-- | arch/m68knommu/platform/68328/ints.c | 130 | ||||
-rw-r--r-- | arch/m68knommu/platform/68360/entry.S | 6 | ||||
-rw-r--r-- | arch/m68knommu/platform/68360/ints.c | 233 |
13 files changed, 155 insertions, 673 deletions
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index adc64a2bafbb..1175ceff8b2a 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig | |||
@@ -45,6 +45,10 @@ config GENERIC_HWEIGHT | |||
45 | bool | 45 | bool |
46 | default y | 46 | default y |
47 | 47 | ||
48 | config GENERIC_HARDIRQS | ||
49 | bool | ||
50 | default y | ||
51 | |||
48 | config GENERIC_CALIBRATE_DELAY | 52 | config GENERIC_CALIBRATE_DELAY |
49 | bool | 53 | bool |
50 | default y | 54 | default y |
diff --git a/arch/m68knommu/kernel/Makefile b/arch/m68knommu/kernel/Makefile index 1c6cd1ab571e..1524b39ad63f 100644 --- a/arch/m68knommu/kernel/Makefile +++ b/arch/m68knommu/kernel/Makefile | |||
@@ -4,8 +4,8 @@ | |||
4 | 4 | ||
5 | extra-y := vmlinux.lds | 5 | extra-y := vmlinux.lds |
6 | 6 | ||
7 | obj-y += dma.o entry.o init_task.o m68k_ksyms.o process.o ptrace.o semaphore.o \ | 7 | obj-y += dma.o entry.o init_task.o irq.o m68k_ksyms.o process.o ptrace.o \ |
8 | setup.o signal.o syscalltable.o sys_m68k.o time.o traps.o | 8 | semaphore.o setup.o signal.o syscalltable.o sys_m68k.o time.o traps.o |
9 | 9 | ||
10 | obj-$(CONFIG_MODULES) += module.o | 10 | obj-$(CONFIG_MODULES) += module.o |
11 | obj-$(CONFIG_COMEMPCI) += comempci.o | 11 | obj-$(CONFIG_COMEMPCI) += comempci.o |
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c index 7cd183d346ef..d97b89bae53c 100644 --- a/arch/m68knommu/kernel/asm-offsets.c +++ b/arch/m68knommu/kernel/asm-offsets.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/hardirq.h> | 15 | #include <linux/hardirq.h> |
16 | #include <asm/bootinfo.h> | 16 | #include <asm/bootinfo.h> |
17 | #include <asm/irq.h> | 17 | #include <asm/irq.h> |
18 | #include <asm/irqnode.h> | ||
19 | #include <asm/thread_info.h> | 18 | #include <asm/thread_info.h> |
20 | 19 | ||
21 | #define DEFINE(sym, val) \ | 20 | #define DEFINE(sym, val) \ |
@@ -72,10 +71,6 @@ int main(void) | |||
72 | #else | 71 | #else |
73 | /* bitfields are a bit difficult */ | 72 | /* bitfields are a bit difficult */ |
74 | DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4); | 73 | DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4); |
75 | /* offsets into the irq_handler struct */ | ||
76 | DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler)); | ||
77 | DEFINE(IRQ_DEVID, offsetof(struct irq_node, dev_id)); | ||
78 | DEFINE(IRQ_NEXT, offsetof(struct irq_node, next)); | ||
79 | #endif | 74 | #endif |
80 | 75 | ||
81 | /* offsets into the kernel_stat struct */ | 76 | /* offsets into the kernel_stat struct */ |
diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68knommu/kernel/irq.c new file mode 100644 index 000000000000..bba1bb48a21f --- /dev/null +++ b/arch/m68knommu/kernel/irq.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * irq.c | ||
3 | * | ||
4 | * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com> | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file COPYING in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/kernel_stat.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/seq_file.h> | ||
18 | #include <asm/system.h> | ||
19 | #include <asm/traps.h> | ||
20 | |||
21 | asmlinkage void do_IRQ(int irq, struct pt_regs *regs) | ||
22 | { | ||
23 | struct pt_regs *oldregs = set_irq_regs(regs); | ||
24 | |||
25 | irq_enter(); | ||
26 | __do_IRQ(irq); | ||
27 | irq_exit(); | ||
28 | |||
29 | set_irq_regs(oldregs); | ||
30 | } | ||
31 | |||
32 | void ack_bad_irq(unsigned int irq) | ||
33 | { | ||
34 | printk(KERN_ERR "IRQ: unexpected irq=%d\n", irq); | ||
35 | } | ||
36 | |||
37 | static struct irq_chip m_irq_chip = { | ||
38 | .name = "M68K-INTC", | ||
39 | .enable = enable_vector, | ||
40 | .disable = disable_vector, | ||
41 | .ack = ack_vector, | ||
42 | }; | ||
43 | |||
44 | void __init init_IRQ(void) | ||
45 | { | ||
46 | int irq; | ||
47 | |||
48 | init_vectors(); | ||
49 | |||
50 | for (irq = 0; (irq < NR_IRQS); irq++) { | ||
51 | irq_desc[irq].status = IRQ_DISABLED; | ||
52 | irq_desc[irq].action = NULL; | ||
53 | irq_desc[irq].depth = 1; | ||
54 | irq_desc[irq].chip = &m_irq_chip; | ||
55 | } | ||
56 | } | ||
57 | |||
58 | int show_interrupts(struct seq_file *p, void *v) | ||
59 | { | ||
60 | struct irqaction *ap; | ||
61 | int irq = *((loff_t *) v); | ||
62 | |||
63 | if (irq == 0) | ||
64 | seq_puts(p, " CPU0\n"); | ||
65 | |||
66 | if (irq < NR_IRQS) { | ||
67 | ap = irq_desc[irq].action; | ||
68 | if (ap) { | ||
69 | seq_printf(p, "%3d: ", irq); | ||
70 | seq_printf(p, "%10u ", kstat_irqs(irq)); | ||
71 | seq_printf(p, "%14s ", irq_desc[irq].chip->name); | ||
72 | |||
73 | seq_printf(p, "%s", ap->name); | ||
74 | for (ap = ap->next; ap; ap = ap->next) | ||
75 | seq_printf(p, ", %s", ap->name); | ||
76 | seq_putc(p, '\n'); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c index fde04e1757f7..9c943a4accc0 100644 --- a/arch/m68knommu/kernel/traps.c +++ b/arch/m68knommu/kernel/traps.c | |||
@@ -62,8 +62,6 @@ static char const * const vec_names[] = { | |||
62 | 62 | ||
63 | void __init trap_init(void) | 63 | void __init trap_init(void) |
64 | { | 64 | { |
65 | if (mach_trap_init) | ||
66 | mach_trap_init(); | ||
67 | } | 65 | } |
68 | 66 | ||
69 | void die_if_kernel(char *str, struct pt_regs *fp, int nr) | 67 | void die_if_kernel(char *str, struct pt_regs *fp, int nr) |
diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile index 2fd37dcc309b..719a313494bc 100644 --- a/arch/m68knommu/platform/5307/Makefile +++ b/arch/m68knommu/platform/5307/Makefile | |||
@@ -16,7 +16,7 @@ ifdef CONFIG_FULLDEBUG | |||
16 | AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 | 16 | AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 |
17 | endif | 17 | endif |
18 | 18 | ||
19 | obj-$(CONFIG_COLDFIRE) += entry.o vectors.o ints.o | 19 | obj-$(CONFIG_COLDFIRE) += entry.o vectors.o |
20 | obj-$(CONFIG_M5206) += timers.o | 20 | obj-$(CONFIG_M5206) += timers.o |
21 | obj-$(CONFIG_M5206e) += timers.o | 21 | obj-$(CONFIG_M5206e) += timers.o |
22 | obj-$(CONFIG_M520x) += pit.o | 22 | obj-$(CONFIG_M520x) += pit.o |
diff --git a/arch/m68knommu/platform/5307/entry.S b/arch/m68knommu/platform/5307/entry.S index f0dba84d9101..c358aebe0af3 100644 --- a/arch/m68knommu/platform/5307/entry.S +++ b/arch/m68knommu/platform/5307/entry.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/m68knommu/platform/5307/entry.S | 2 | * linux/arch/m68knommu/platform/5307/entry.S |
3 | * | 3 | * |
4 | * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com) | 4 | * Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com) |
5 | * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>, | 5 | * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>, |
6 | * Kenneth Albanowski <kjahds@kjahds.com>, | 6 | * Kenneth Albanowski <kjahds@kjahds.com>, |
7 | * Copyright (C) 2000 Lineo Inc. (www.lineo.com) | 7 | * Copyright (C) 2000 Lineo Inc. (www.lineo.com) |
@@ -155,34 +155,21 @@ Lsignal_return: | |||
155 | 155 | ||
156 | /* | 156 | /* |
157 | * This is the generic interrupt handler (for all hardware interrupt | 157 | * This is the generic interrupt handler (for all hardware interrupt |
158 | * sources). It figures out the vector number and calls the appropriate | 158 | * sources). Calls upto high level code to do all the work. |
159 | * interrupt service routine directly. | ||
160 | */ | 159 | */ |
161 | ENTRY(inthandler) | 160 | ENTRY(inthandler) |
162 | SAVE_ALL | 161 | SAVE_ALL |
163 | moveq #-1,%d0 | 162 | moveq #-1,%d0 |
164 | movel %d0,%sp@(PT_ORIG_D0) | 163 | movel %d0,%sp@(PT_ORIG_D0) |
165 | addql #1,local_irq_count | ||
166 | 164 | ||
167 | movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */ | 165 | movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */ |
168 | andl #0x03fc,%d0 /* mask out vector only */ | 166 | andl #0x03fc,%d0 /* mask out vector only */ |
169 | 167 | ||
170 | leal per_cpu__kstat+STAT_IRQ,%a0 | 168 | movel %sp,%sp@- /* push regs arg */ |
171 | addql #1,%a0@(%d0) | ||
172 | |||
173 | lsrl #2,%d0 /* calculate real vector # */ | 169 | lsrl #2,%d0 /* calculate real vector # */ |
174 | movel %d0,%d1 /* calculate array offset */ | 170 | movel %d0,%sp@- /* push vector number */ |
175 | lsll #4,%d1 | 171 | jbsr do_IRQ /* call high level irq handler */ |
176 | lea irq_list,%a0 | 172 | lea %sp@(8),%sp /* pop args off stack */ |
177 | addl %d1,%a0 /* pointer to array struct */ | ||
178 | |||
179 | movel %sp,%sp@- /* push regs arg onto stack */ | ||
180 | movel %a0@(8),%sp@- /* push devid arg */ | ||
181 | movel %d0,%sp@- /* push vector # on stack */ | ||
182 | |||
183 | movel %a0@,%a0 /* get function to call */ | ||
184 | jbsr %a0@ /* call vector handler */ | ||
185 | lea %sp@(12),%sp /* pop parameters off stack */ | ||
186 | 173 | ||
187 | bra ret_from_interrupt /* this was fallthrough */ | 174 | bra ret_from_interrupt /* this was fallthrough */ |
188 | 175 | ||
@@ -198,24 +185,15 @@ ENTRY(fasthandler) | |||
198 | movew %sp@(PT_FORMATVEC),%d0 | 185 | movew %sp@(PT_FORMATVEC),%d0 |
199 | andl #0x03fc,%d0 /* mask out vector only */ | 186 | andl #0x03fc,%d0 /* mask out vector only */ |
200 | 187 | ||
201 | leal per_cpu__kstat+STAT_IRQ,%a0 | 188 | movel %sp,%sp@- /* push regs arg */ |
202 | addql #1,%a0@(%d0) | ||
203 | |||
204 | movel %sp,%sp@- /* push regs arg onto stack */ | ||
205 | clrl %sp@- /* push devid arg */ | ||
206 | lsrl #2,%d0 /* calculate real vector # */ | 189 | lsrl #2,%d0 /* calculate real vector # */ |
207 | movel %d0,%sp@- /* push vector # on stack */ | 190 | movel %d0,%sp@- /* push vector number */ |
208 | 191 | jbsr do_IRQ /* call high level irq handler */ | |
209 | lsll #4,%d0 /* adjust for array offset */ | 192 | lea %sp@(8),%sp /* pop args off stack */ |
210 | lea irq_list,%a0 | ||
211 | movel %a0@(%d0),%a0 /* get function to call */ | ||
212 | jbsr %a0@ /* call vector handler */ | ||
213 | lea %sp@(12),%sp /* pop parameters off stack */ | ||
214 | 193 | ||
215 | RESTORE_LOCAL | 194 | RESTORE_LOCAL |
216 | 195 | ||
217 | ENTRY(ret_from_interrupt) | 196 | ENTRY(ret_from_interrupt) |
218 | subql #1,local_irq_count | ||
219 | jeq 2f | 197 | jeq 2f |
220 | 1: | 198 | 1: |
221 | RESTORE_ALL | 199 | RESTORE_ALL |
diff --git a/arch/m68knommu/platform/5307/ints.c b/arch/m68knommu/platform/5307/ints.c deleted file mode 100644 index 751633038c4b..000000000000 --- a/arch/m68knommu/platform/5307/ints.c +++ /dev/null | |||
@@ -1,279 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/m68knommu/kernel/ints.c -- General interrupt handling code | ||
3 | * | ||
4 | * Copyright (C) 1999-2002 Greg Ungerer (gerg@snapgear.com) | ||
5 | * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>, | ||
6 | * Kenneth Albanowski <kjahds@kjahds.com>, | ||
7 | * Copyright (C) 2000 Lineo Inc. (www.lineo.com) | ||
8 | * | ||
9 | * Based on: | ||
10 | * | ||
11 | * linux/arch/m68k/kernel/ints.c -- Linux/m68k general interrupt handling code | ||
12 | * | ||
13 | * This file is subject to the terms and conditions of the GNU General Public | ||
14 | * License. See the file COPYING in the main directory of this archive | ||
15 | * for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/kernel_stat.h> | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/seq_file.h> | ||
26 | |||
27 | #include <asm/system.h> | ||
28 | #include <asm/irq.h> | ||
29 | #include <asm/irqnode.h> | ||
30 | #include <asm/traps.h> | ||
31 | #include <asm/page.h> | ||
32 | #include <asm/machdep.h> | ||
33 | |||
34 | /* | ||
35 | * This table stores the address info for each vector handler. | ||
36 | */ | ||
37 | struct irq_entry irq_list[SYS_IRQS]; | ||
38 | |||
39 | #define NUM_IRQ_NODES 16 | ||
40 | static irq_node_t nodes[NUM_IRQ_NODES]; | ||
41 | |||
42 | /* The number of spurious interrupts */ | ||
43 | volatile unsigned int num_spurious; | ||
44 | |||
45 | unsigned int local_irq_count[NR_CPUS]; | ||
46 | |||
47 | static irqreturn_t default_irq_handler(int irq, void *ptr) | ||
48 | { | ||
49 | #if 1 | ||
50 | printk(KERN_INFO "%s(%d): default irq handler vec=%d [0x%x]\n", | ||
51 | __FILE__, __LINE__, irq, irq); | ||
52 | #endif | ||
53 | return(IRQ_HANDLED); | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * void init_IRQ(void) | ||
58 | * | ||
59 | * Parameters: None | ||
60 | * | ||
61 | * Returns: Nothing | ||
62 | * | ||
63 | * This function should be called during kernel startup to initialize | ||
64 | * the IRQ handling routines. | ||
65 | */ | ||
66 | |||
67 | void __init init_IRQ(void) | ||
68 | { | ||
69 | int i; | ||
70 | |||
71 | for (i = 0; i < SYS_IRQS; i++) { | ||
72 | if (mach_default_handler) | ||
73 | irq_list[i].handler = mach_default_handler; | ||
74 | else | ||
75 | irq_list[i].handler = default_irq_handler; | ||
76 | irq_list[i].flags = IRQ_FLG_STD; | ||
77 | irq_list[i].dev_id = NULL; | ||
78 | irq_list[i].devname = NULL; | ||
79 | } | ||
80 | |||
81 | for (i = 0; i < NUM_IRQ_NODES; i++) | ||
82 | nodes[i].handler = NULL; | ||
83 | |||
84 | if (mach_init_IRQ) | ||
85 | mach_init_IRQ(); | ||
86 | } | ||
87 | |||
88 | irq_node_t *new_irq_node(void) | ||
89 | { | ||
90 | irq_node_t *node; | ||
91 | short i; | ||
92 | |||
93 | for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) | ||
94 | if (!node->handler) | ||
95 | return node; | ||
96 | |||
97 | printk(KERN_INFO "new_irq_node: out of nodes\n"); | ||
98 | return NULL; | ||
99 | } | ||
100 | |||
101 | int request_irq( | ||
102 | unsigned int irq, | ||
103 | irq_handler_t handler, | ||
104 | unsigned long flags, | ||
105 | const char *devname, | ||
106 | void *dev_id) | ||
107 | { | ||
108 | if (irq < 0 || irq >= NR_IRQS) { | ||
109 | printk(KERN_WARNING "%s: Incorrect IRQ %d from %s\n", __FUNCTION__, | ||
110 | irq, devname); | ||
111 | return -ENXIO; | ||
112 | } | ||
113 | |||
114 | if (!(irq_list[irq].flags & IRQ_FLG_STD)) { | ||
115 | if (irq_list[irq].flags & IRQ_FLG_LOCK) { | ||
116 | printk(KERN_WARNING "%s: IRQ %d from %s is not replaceable\n", | ||
117 | __FUNCTION__, irq, irq_list[irq].devname); | ||
118 | return -EBUSY; | ||
119 | } | ||
120 | if (flags & IRQ_FLG_REPLACE) { | ||
121 | printk(KERN_WARNING "%s: %s can't replace IRQ %d from %s\n", | ||
122 | __FUNCTION__, devname, irq, irq_list[irq].devname); | ||
123 | return -EBUSY; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | if (flags & IRQ_FLG_FAST) { | ||
128 | extern asmlinkage void fasthandler(void); | ||
129 | extern void set_evector(int vecnum, void (*handler)(void)); | ||
130 | set_evector(irq, fasthandler); | ||
131 | } | ||
132 | |||
133 | irq_list[irq].handler = handler; | ||
134 | irq_list[irq].flags = flags; | ||
135 | irq_list[irq].dev_id = dev_id; | ||
136 | irq_list[irq].devname = devname; | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | EXPORT_SYMBOL(request_irq); | ||
141 | |||
142 | void free_irq(unsigned int irq, void *dev_id) | ||
143 | { | ||
144 | if (irq >= NR_IRQS) { | ||
145 | printk(KERN_WARNING "%s: Incorrect IRQ %d\n", __FUNCTION__, irq); | ||
146 | return; | ||
147 | } | ||
148 | |||
149 | if (irq_list[irq].dev_id != dev_id) | ||
150 | printk(KERN_WARNING "%s: Removing probably wrong IRQ %d from %s\n", | ||
151 | __FUNCTION__, irq, irq_list[irq].devname); | ||
152 | |||
153 | if (irq_list[irq].flags & IRQ_FLG_FAST) { | ||
154 | extern asmlinkage void inthandler(void); | ||
155 | extern void set_evector(int vecnum, void (*handler)(void)); | ||
156 | set_evector(irq, inthandler); | ||
157 | } | ||
158 | |||
159 | if (mach_default_handler) | ||
160 | irq_list[irq].handler = mach_default_handler; | ||
161 | else | ||
162 | irq_list[irq].handler = default_irq_handler; | ||
163 | irq_list[irq].flags = IRQ_FLG_STD; | ||
164 | irq_list[irq].dev_id = NULL; | ||
165 | irq_list[irq].devname = NULL; | ||
166 | } | ||
167 | |||
168 | EXPORT_SYMBOL(free_irq); | ||
169 | |||
170 | |||
171 | int sys_request_irq(unsigned int irq, irq_handler_t handler, | ||
172 | unsigned long flags, const char *devname, void *dev_id) | ||
173 | { | ||
174 | if (irq > IRQ7) { | ||
175 | printk(KERN_WARNING "%s: Incorrect IRQ %d from %s\n", | ||
176 | __FUNCTION__, irq, devname); | ||
177 | return -ENXIO; | ||
178 | } | ||
179 | |||
180 | #if 0 | ||
181 | if (!(irq_list[irq].flags & IRQ_FLG_STD)) { | ||
182 | if (irq_list[irq].flags & IRQ_FLG_LOCK) { | ||
183 | printk(KERN_WARNING "%s: IRQ %d from %s is not replaceable\n", | ||
184 | __FUNCTION__, irq, irq_list[irq].devname); | ||
185 | return -EBUSY; | ||
186 | } | ||
187 | if (!(flags & IRQ_FLG_REPLACE)) { | ||
188 | printk(KERN_WARNING "%s: %s can't replace IRQ %d from %s\n", | ||
189 | __FUNCTION__, devname, irq, irq_list[irq].devname); | ||
190 | return -EBUSY; | ||
191 | } | ||
192 | } | ||
193 | #endif | ||
194 | |||
195 | irq_list[irq].handler = handler; | ||
196 | irq_list[irq].flags = flags; | ||
197 | irq_list[irq].dev_id = dev_id; | ||
198 | irq_list[irq].devname = devname; | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | void sys_free_irq(unsigned int irq, void *dev_id) | ||
203 | { | ||
204 | if (irq > IRQ7) { | ||
205 | printk(KERN_WARNING "%s: Incorrect IRQ %d\n", __FUNCTION__, irq); | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | if (irq_list[irq].dev_id != dev_id) | ||
210 | printk(KERN_WARNING "%s: Removing probably wrong IRQ %d from %s\n", | ||
211 | __FUNCTION__, irq, irq_list[irq].devname); | ||
212 | |||
213 | irq_list[irq].handler = mach_default_handler; | ||
214 | irq_list[irq].flags = 0; | ||
215 | irq_list[irq].dev_id = NULL; | ||
216 | irq_list[irq].devname = NULL; | ||
217 | } | ||
218 | |||
219 | /* | ||
220 | * Do we need these probe functions on the m68k? | ||
221 | * | ||
222 | * ... may be useful with ISA devices | ||
223 | */ | ||
224 | unsigned long probe_irq_on (void) | ||
225 | { | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | EXPORT_SYMBOL(probe_irq_on); | ||
230 | |||
231 | int probe_irq_off (unsigned long irqs) | ||
232 | { | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | EXPORT_SYMBOL(probe_irq_off); | ||
237 | |||
238 | asmlinkage void process_int(unsigned long vec, struct pt_regs *fp) | ||
239 | { | ||
240 | if (vec >= VEC_INT1 && vec <= VEC_INT7) { | ||
241 | vec -= VEC_SPUR; | ||
242 | kstat_cpu(0).irqs[vec]++; | ||
243 | irq_list[vec].handler(vec, irq_list[vec].dev_id); | ||
244 | } else { | ||
245 | if (mach_process_int) | ||
246 | mach_process_int(vec, fp); | ||
247 | else | ||
248 | panic("Can't process interrupt vector %ld\n", vec); | ||
249 | return; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | |||
254 | int show_interrupts(struct seq_file *p, void *v) | ||
255 | { | ||
256 | int i = *(loff_t *) v; | ||
257 | |||
258 | if (i < NR_IRQS) { | ||
259 | if (! (irq_list[i].flags & IRQ_FLG_STD)) { | ||
260 | seq_printf(p, "%3d: %10u ", i, | ||
261 | (i ? kstat_cpu(0).irqs[i] : num_spurious)); | ||
262 | if (irq_list[i].flags & IRQ_FLG_LOCK) | ||
263 | seq_printf(p, "L "); | ||
264 | else | ||
265 | seq_printf(p, " "); | ||
266 | seq_printf(p, "%s\n", irq_list[i].devname); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | if (i == NR_IRQS && mach_get_irq_list) | ||
271 | mach_get_irq_list(p, v); | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | void init_irq_proc(void) | ||
276 | { | ||
277 | /* Insert /proc/irq driver here */ | ||
278 | } | ||
279 | |||
diff --git a/arch/m68knommu/platform/5307/vectors.c b/arch/m68knommu/platform/5307/vectors.c index 2a8b0d044ce5..6cf894620234 100644 --- a/arch/m68knommu/platform/5307/vectors.c +++ b/arch/m68knommu/platform/5307/vectors.c | |||
@@ -3,23 +3,17 @@ | |||
3 | /* | 3 | /* |
4 | * linux/arch/m68knommu/platform/5307/vectors.c | 4 | * linux/arch/m68knommu/platform/5307/vectors.c |
5 | * | 5 | * |
6 | * Copyright (C) 1999-2003, Greg Ungerer <gerg@snapgear.com> | 6 | * Copyright (C) 1999-2007, Greg Ungerer <gerg@snapgear.com> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | /***************************************************************************/ | 9 | /***************************************************************************/ |
10 | 10 | ||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/sched.h> | ||
13 | #include <linux/param.h> | ||
14 | #include <linux/init.h> | 12 | #include <linux/init.h> |
15 | #include <linux/unistd.h> | 13 | #include <linux/irq.h> |
16 | #include <linux/delay.h> | ||
17 | #include <asm/irq.h> | ||
18 | #include <asm/dma.h> | ||
19 | #include <asm/traps.h> | 14 | #include <asm/traps.h> |
20 | #include <asm/machdep.h> | 15 | #include <asm/machdep.h> |
21 | #include <asm/coldfire.h> | 16 | #include <asm/coldfire.h> |
22 | #include <asm/mcftimer.h> | ||
23 | #include <asm/mcfsim.h> | 17 | #include <asm/mcfsim.h> |
24 | #include <asm/mcfdma.h> | 18 | #include <asm/mcfdma.h> |
25 | #include <asm/mcfwdebug.h> | 19 | #include <asm/mcfwdebug.h> |
@@ -56,7 +50,7 @@ asmlinkage void trap(void); | |||
56 | asmlinkage void system_call(void); | 50 | asmlinkage void system_call(void); |
57 | asmlinkage void inthandler(void); | 51 | asmlinkage void inthandler(void); |
58 | 52 | ||
59 | void __init coldfire_trap_init(void) | 53 | void __init init_vectors(void) |
60 | { | 54 | { |
61 | int i; | 55 | int i; |
62 | 56 | ||
@@ -86,6 +80,23 @@ void __init coldfire_trap_init(void) | |||
86 | 80 | ||
87 | /***************************************************************************/ | 81 | /***************************************************************************/ |
88 | 82 | ||
83 | void enable_vector(unsigned int irq) | ||
84 | { | ||
85 | /* Currently no action on ColdFire */ | ||
86 | } | ||
87 | |||
88 | void disable_vector(unsigned int irq) | ||
89 | { | ||
90 | /* Currently no action on ColdFire */ | ||
91 | } | ||
92 | |||
93 | void ack_vector(unsigned int irq) | ||
94 | { | ||
95 | /* Currently no action on ColdFire */ | ||
96 | } | ||
97 | |||
98 | /***************************************************************************/ | ||
99 | |||
89 | void coldfire_reset(void) | 100 | void coldfire_reset(void) |
90 | { | 101 | { |
91 | HARD_RESET_NOW(); | 102 | HARD_RESET_NOW(); |
diff --git a/arch/m68knommu/platform/68328/entry.S b/arch/m68knommu/platform/68328/entry.S index f97862715450..b1aef72f3baf 100644 --- a/arch/m68knommu/platform/68328/entry.S +++ b/arch/m68knommu/platform/68328/entry.S | |||
@@ -133,7 +133,6 @@ Lreturn: | |||
133 | */ | 133 | */ |
134 | inthandler1: | 134 | inthandler1: |
135 | SAVE_ALL | 135 | SAVE_ALL |
136 | addql #1,local_irq_count /* put exception # in d0*/ | ||
137 | movew %sp@(PT_VECTOR), %d0 | 136 | movew %sp@(PT_VECTOR), %d0 |
138 | and #0x3ff, %d0 | 137 | and #0x3ff, %d0 |
139 | 138 | ||
@@ -145,7 +144,6 @@ inthandler1: | |||
145 | 144 | ||
146 | inthandler2: | 145 | inthandler2: |
147 | SAVE_ALL | 146 | SAVE_ALL |
148 | addql #1,local_irq_count /* put exception # in d0*/ | ||
149 | movew %sp@(PT_VECTOR), %d0 | 147 | movew %sp@(PT_VECTOR), %d0 |
150 | and #0x3ff, %d0 | 148 | and #0x3ff, %d0 |
151 | 149 | ||
@@ -157,7 +155,6 @@ inthandler2: | |||
157 | 155 | ||
158 | inthandler3: | 156 | inthandler3: |
159 | SAVE_ALL | 157 | SAVE_ALL |
160 | addql #1,local_irq_count /* put exception # in d0*/ | ||
161 | movew %sp@(PT_VECTOR), %d0 | 158 | movew %sp@(PT_VECTOR), %d0 |
162 | and #0x3ff, %d0 | 159 | and #0x3ff, %d0 |
163 | 160 | ||
@@ -169,7 +166,6 @@ inthandler3: | |||
169 | 166 | ||
170 | inthandler4: | 167 | inthandler4: |
171 | SAVE_ALL | 168 | SAVE_ALL |
172 | addql #1,local_irq_count /* put exception # in d0*/ | ||
173 | movew %sp@(PT_VECTOR), %d0 | 169 | movew %sp@(PT_VECTOR), %d0 |
174 | and #0x3ff, %d0 | 170 | and #0x3ff, %d0 |
175 | 171 | ||
@@ -181,7 +177,6 @@ inthandler4: | |||
181 | 177 | ||
182 | inthandler5: | 178 | inthandler5: |
183 | SAVE_ALL | 179 | SAVE_ALL |
184 | addql #1,local_irq_count /* put exception # in d0*/ | ||
185 | movew %sp@(PT_VECTOR), %d0 | 180 | movew %sp@(PT_VECTOR), %d0 |
186 | and #0x3ff, %d0 | 181 | and #0x3ff, %d0 |
187 | 182 | ||
@@ -193,7 +188,6 @@ inthandler5: | |||
193 | 188 | ||
194 | inthandler6: | 189 | inthandler6: |
195 | SAVE_ALL | 190 | SAVE_ALL |
196 | addql #1,local_irq_count /* put exception # in d0*/ | ||
197 | movew %sp@(PT_VECTOR), %d0 | 191 | movew %sp@(PT_VECTOR), %d0 |
198 | and #0x3ff, %d0 | 192 | and #0x3ff, %d0 |
199 | 193 | ||
@@ -205,7 +199,6 @@ inthandler6: | |||
205 | 199 | ||
206 | inthandler7: | 200 | inthandler7: |
207 | SAVE_ALL | 201 | SAVE_ALL |
208 | addql #1,local_irq_count /* put exception # in d0*/ | ||
209 | movew %sp@(PT_VECTOR), %d0 | 202 | movew %sp@(PT_VECTOR), %d0 |
210 | and #0x3ff, %d0 | 203 | and #0x3ff, %d0 |
211 | 204 | ||
@@ -217,7 +210,6 @@ inthandler7: | |||
217 | 210 | ||
218 | inthandler: | 211 | inthandler: |
219 | SAVE_ALL | 212 | SAVE_ALL |
220 | addql #1,local_irq_count /* put exception # in d0*/ | ||
221 | movew %sp@(PT_VECTOR), %d0 | 213 | movew %sp@(PT_VECTOR), %d0 |
222 | and #0x3ff, %d0 | 214 | and #0x3ff, %d0 |
223 | 215 | ||
@@ -228,7 +220,6 @@ inthandler: | |||
228 | bra ret_from_interrupt | 220 | bra ret_from_interrupt |
229 | 221 | ||
230 | ret_from_interrupt: | 222 | ret_from_interrupt: |
231 | subql #1,local_irq_count | ||
232 | jeq 1f | 223 | jeq 1f |
233 | 2: | 224 | 2: |
234 | RESTORE_ALL | 225 | RESTORE_ALL |
@@ -238,7 +229,6 @@ ret_from_interrupt: | |||
238 | jhi 2b | 229 | jhi 2b |
239 | 230 | ||
240 | /* check if we need to do software interrupts */ | 231 | /* check if we need to do software interrupts */ |
241 | movel local_irq_count,%d0 | ||
242 | jeq ret_from_exception | 232 | jeq ret_from_exception |
243 | 233 | ||
244 | pea ret_from_exception | 234 | pea ret_from_exception |
diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c index 3de6e337554e..72e56d554f4f 100644 --- a/arch/m68knommu/platform/68328/ints.c +++ b/arch/m68knommu/platform/68328/ints.c | |||
@@ -9,21 +9,14 @@ | |||
9 | * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com> | 9 | * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com> |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/types.h> | 12 | #include <linux/types.h> |
14 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
15 | #include <linux/sched.h> | 14 | #include <linux/init.h> |
16 | #include <linux/kernel_stat.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
19 | 16 | #include <linux/irq.h> | |
20 | #include <asm/system.h> | ||
21 | #include <asm/irq.h> | ||
22 | #include <asm/irqnode.h> | ||
23 | #include <asm/traps.h> | 17 | #include <asm/traps.h> |
24 | #include <asm/io.h> | 18 | #include <asm/io.h> |
25 | #include <asm/machdep.h> | 19 | #include <asm/machdep.h> |
26 | #include <asm/setup.h> | ||
27 | 20 | ||
28 | #if defined(CONFIG_M68328) | 21 | #if defined(CONFIG_M68328) |
29 | #include <asm/MC68328.h> | 22 | #include <asm/MC68328.h> |
@@ -79,16 +72,12 @@ extern e_vector *_ramvec; | |||
79 | 72 | ||
80 | /* The number of spurious interrupts */ | 73 | /* The number of spurious interrupts */ |
81 | volatile unsigned int num_spurious; | 74 | volatile unsigned int num_spurious; |
82 | unsigned int local_irq_count[NR_CPUS]; | ||
83 | |||
84 | /* irq node variables for the 32 (potential) on chip sources */ | ||
85 | static irq_node_t int_irq_list[NR_IRQS]; | ||
86 | 75 | ||
87 | /* | 76 | /* |
88 | * This function should be called during kernel startup to initialize | 77 | * This function should be called during kernel startup to initialize |
89 | * the IRQ handling routines. | 78 | * the machine vector table. |
90 | */ | 79 | */ |
91 | void init_IRQ(void) | 80 | void __init init_vectors(void) |
92 | { | 81 | { |
93 | int i; | 82 | int i; |
94 | 83 | ||
@@ -108,96 +97,10 @@ void init_IRQ(void) | |||
108 | 97 | ||
109 | IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */ | 98 | IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */ |
110 | 99 | ||
111 | /* initialize handlers */ | ||
112 | for (i = 0; i < NR_IRQS; i++) { | ||
113 | int_irq_list[i].handler = bad_interrupt; | ||
114 | int_irq_list[i].flags = IRQ_FLG_STD; | ||
115 | int_irq_list[i].dev_id = NULL; | ||
116 | int_irq_list[i].devname = NULL; | ||
117 | } | ||
118 | |||
119 | /* turn off all interrupts */ | 100 | /* turn off all interrupts */ |
120 | IMR = ~0; | 101 | IMR = ~0; |
121 | } | 102 | } |
122 | 103 | ||
123 | int request_irq( | ||
124 | unsigned int irq, | ||
125 | irq_handler_t handler, | ||
126 | unsigned long flags, | ||
127 | const char *devname, | ||
128 | void *dev_id) | ||
129 | { | ||
130 | if (irq >= NR_IRQS) { | ||
131 | printk (KERN_ERR "%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname); | ||
132 | return -ENXIO; | ||
133 | } | ||
134 | |||
135 | if (!(int_irq_list[irq].flags & IRQ_FLG_STD)) { | ||
136 | if (int_irq_list[irq].flags & IRQ_FLG_LOCK) { | ||
137 | printk(KERN_ERR "%s: IRQ %d from %s is not replaceable\n", | ||
138 | __FUNCTION__, irq, int_irq_list[irq].devname); | ||
139 | return -EBUSY; | ||
140 | } | ||
141 | if (flags & IRQ_FLG_REPLACE) { | ||
142 | printk(KERN_ERR "%s: %s can't replace IRQ %d from %s\n", | ||
143 | __FUNCTION__, devname, irq, int_irq_list[irq].devname); | ||
144 | return -EBUSY; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | int_irq_list[irq].handler = handler; | ||
149 | int_irq_list[irq].flags = flags; | ||
150 | int_irq_list[irq].dev_id = dev_id; | ||
151 | int_irq_list[irq].devname = devname; | ||
152 | |||
153 | IMR &= ~(1<<irq); | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | EXPORT_SYMBOL(request_irq); | ||
159 | |||
160 | void free_irq(unsigned int irq, void *dev_id) | ||
161 | { | ||
162 | if (irq >= NR_IRQS) { | ||
163 | printk (KERN_ERR "%s: Unknown IRQ %d\n", __FUNCTION__, irq); | ||
164 | return; | ||
165 | } | ||
166 | |||
167 | if (int_irq_list[irq].dev_id != dev_id) | ||
168 | printk(KERN_INFO "%s: removing probably wrong IRQ %d from %s\n", | ||
169 | __FUNCTION__, irq, int_irq_list[irq].devname); | ||
170 | |||
171 | int_irq_list[irq].handler = bad_interrupt; | ||
172 | int_irq_list[irq].flags = IRQ_FLG_STD; | ||
173 | int_irq_list[irq].dev_id = NULL; | ||
174 | int_irq_list[irq].devname = NULL; | ||
175 | |||
176 | IMR |= 1<<irq; | ||
177 | } | ||
178 | |||
179 | EXPORT_SYMBOL(free_irq); | ||
180 | |||
181 | int show_interrupts(struct seq_file *p, void *v) | ||
182 | { | ||
183 | int i = *(loff_t *) v; | ||
184 | |||
185 | if (i < NR_IRQS) { | ||
186 | if (int_irq_list[i].devname) { | ||
187 | seq_printf(p, "%3d: %10u ", i, kstat_cpu(0).irqs[i]); | ||
188 | if (int_irq_list[i].flags & IRQ_FLG_LOCK) | ||
189 | seq_printf(p, "L "); | ||
190 | else | ||
191 | seq_printf(p, " "); | ||
192 | seq_printf(p, "%s\n", int_irq_list[i].devname); | ||
193 | } | ||
194 | } | ||
195 | if (i == NR_IRQS) | ||
196 | seq_printf(p, " : %10u spurious\n", num_spurious); | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | /* The 68k family did not have a good way to determine the source | 104 | /* The 68k family did not have a good way to determine the source |
202 | * of interrupts until later in the family. The EC000 core does | 105 | * of interrupts until later in the family. The EC000 core does |
203 | * not provide the vector number on the stack, we vector everything | 106 | * not provide the vector number on the stack, we vector everything |
@@ -255,14 +158,23 @@ void process_int(int vec, struct pt_regs *fp) | |||
255 | irq++; | 158 | irq++; |
256 | } | 159 | } |
257 | 160 | ||
258 | kstat_cpu(0).irqs[irq]++; | 161 | do_IRQ(irq, fp); |
259 | |||
260 | if (int_irq_list[irq].handler) { | ||
261 | int_irq_list[irq].handler(irq, int_irq_list[irq].dev_id, fp); | ||
262 | } else { | ||
263 | printk(KERN_ERR "unregistered interrupt %d!\nTurning it off in the IMR...\n", irq); | ||
264 | IMR |= mask; | ||
265 | } | ||
266 | pend &= ~mask; | 162 | pend &= ~mask; |
267 | } | 163 | } |
268 | } | 164 | } |
165 | |||
166 | void enable_vector(unsigned int irq) | ||
167 | { | ||
168 | IMR &= ~(1<<irq); | ||
169 | } | ||
170 | |||
171 | void disable_vector(unsigned int irq) | ||
172 | { | ||
173 | IMR |= (1<<irq); | ||
174 | } | ||
175 | |||
176 | void ack_vector(unsigned int irq) | ||
177 | { | ||
178 | /* Nothing needed */ | ||
179 | } | ||
180 | |||
diff --git a/arch/m68knommu/platform/68360/entry.S b/arch/m68knommu/platform/68360/entry.S index f1af8977f294..55dfefe38642 100644 --- a/arch/m68knommu/platform/68360/entry.S +++ b/arch/m68knommu/platform/68360/entry.S | |||
@@ -120,23 +120,21 @@ Lreturn: | |||
120 | RESTORE_ALL | 120 | RESTORE_ALL |
121 | 121 | ||
122 | /* | 122 | /* |
123 | * This is the main interrupt handler, responsible for calling process_int() | 123 | * This is the main interrupt handler, responsible for calling do_IRQ() |
124 | */ | 124 | */ |
125 | inthandler: | 125 | inthandler: |
126 | SAVE_ALL | 126 | SAVE_ALL |
127 | addql #1,local_irq_count /* put exception # in d0*/ | ||
128 | movew %sp@(PT_VECTOR), %d0 | 127 | movew %sp@(PT_VECTOR), %d0 |
129 | and.l #0x3ff, %d0 | 128 | and.l #0x3ff, %d0 |
130 | lsr.l #0x02, %d0 | 129 | lsr.l #0x02, %d0 |
131 | 130 | ||
132 | movel %sp,%sp@- | 131 | movel %sp,%sp@- |
133 | movel %d0,%sp@- /* put vector # on stack*/ | 132 | movel %d0,%sp@- /* put vector # on stack*/ |
134 | jbsr process_int /* process the IRQ*/ | 133 | jbsr do_IRQ /* process the IRQ*/ |
135 | 3: addql #8,%sp /* pop parameters off stack*/ | 134 | 3: addql #8,%sp /* pop parameters off stack*/ |
136 | bra ret_from_interrupt | 135 | bra ret_from_interrupt |
137 | 136 | ||
138 | ret_from_interrupt: | 137 | ret_from_interrupt: |
139 | subql #1,local_irq_count | ||
140 | jeq 1f | 138 | jeq 1f |
141 | 2: | 139 | 2: |
142 | RESTORE_ALL | 140 | RESTORE_ALL |
diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c index 4df3c146eb74..c36781157e09 100644 --- a/arch/m68knommu/platform/68360/ints.c +++ b/arch/m68knommu/platform/68360/ints.c | |||
@@ -10,20 +10,13 @@ | |||
10 | * Copyright (c) 1999 D. Jeff Dionne <jeff@uclinux.org> | 10 | * Copyright (c) 1999 D. Jeff Dionne <jeff@uclinux.org> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/types.h> | 13 | #include <linux/types.h> |
15 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
16 | #include <linux/sched.h> | 15 | #include <linux/init.h> |
17 | #include <linux/kernel_stat.h> | 16 | #include <linux/interrupt.h> |
18 | #include <linux/errno.h> | 17 | #include <linux/irq.h> |
19 | |||
20 | #include <asm/system.h> | ||
21 | #include <asm/irq.h> | ||
22 | #include <asm/irqnode.h> | ||
23 | #include <asm/traps.h> | 18 | #include <asm/traps.h> |
24 | #include <asm/io.h> | ||
25 | #include <asm/machdep.h> | 19 | #include <asm/machdep.h> |
26 | #include <asm/setup.h> | ||
27 | #include <asm/m68360.h> | 20 | #include <asm/m68360.h> |
28 | 21 | ||
29 | /* from quicc/commproc.c: */ | 22 | /* from quicc/commproc.c: */ |
@@ -36,26 +29,19 @@ extern void cpm_interrupt_init(void); | |||
36 | asmlinkage void system_call(void); | 29 | asmlinkage void system_call(void); |
37 | asmlinkage void buserr(void); | 30 | asmlinkage void buserr(void); |
38 | asmlinkage void trap(void); | 31 | asmlinkage void trap(void); |
39 | asmlinkage irqreturn_t bad_interrupt(void); | 32 | asmlinkage void bad_interrupt(void); |
40 | asmlinkage irqreturn_t inthandler(void); | 33 | asmlinkage void inthandler(void); |
41 | 34 | ||
42 | extern void *_ramvec[]; | 35 | extern void *_ramvec[]; |
43 | 36 | ||
44 | /* The number of spurious interrupts */ | 37 | /* The number of spurious interrupts */ |
45 | volatile unsigned int num_spurious; | 38 | volatile unsigned int num_spurious; |
46 | unsigned int local_irq_count[NR_CPUS]; | ||
47 | |||
48 | /* irq node variables for the 32 (potential) on chip sources */ | ||
49 | static irq_node_t int_irq_list[INTERNAL_IRQS]; | ||
50 | |||
51 | static short int_irq_ablecount[INTERNAL_IRQS]; | ||
52 | 39 | ||
53 | /* | 40 | /* |
54 | * This function should be called during kernel startup to initialize | 41 | * This function should be called during kernel startup to initialize |
55 | * IRQ handling routines. | 42 | * the vector table. |
56 | */ | 43 | */ |
57 | 44 | void init_vectors(void) | |
58 | void init_IRQ(void) | ||
59 | { | 45 | { |
60 | int i; | 46 | int i; |
61 | int vba = (CPM_VECTOR_BASE<<4); | 47 | int vba = (CPM_VECTOR_BASE<<4); |
@@ -79,7 +65,6 @@ void init_IRQ(void) | |||
79 | _ramvec[32] = system_call; | 65 | _ramvec[32] = system_call; |
80 | _ramvec[33] = trap; | 66 | _ramvec[33] = trap; |
81 | 67 | ||
82 | |||
83 | cpm_interrupt_init(); | 68 | cpm_interrupt_init(); |
84 | 69 | ||
85 | /* set up CICR for vector base address and irq level */ | 70 | /* set up CICR for vector base address and irq level */ |
@@ -124,212 +109,20 @@ void init_IRQ(void) | |||
124 | 109 | ||
125 | /* turn off all CPM interrupts */ | 110 | /* turn off all CPM interrupts */ |
126 | pquicc->intr_cimr = 0x00000000; | 111 | pquicc->intr_cimr = 0x00000000; |
127 | |||
128 | /* initialize handlers */ | ||
129 | for (i = 0; i < INTERNAL_IRQS; i++) { | ||
130 | int_irq_list[i].handler = NULL; | ||
131 | int_irq_list[i].flags = IRQ_FLG_STD; | ||
132 | int_irq_list[i].dev_id = NULL; | ||
133 | int_irq_list[i].devname = NULL; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | #if 0 | ||
138 | void M68360_insert_irq(irq_node_t **list, irq_node_t *node) | ||
139 | { | ||
140 | unsigned long flags; | ||
141 | irq_node_t *cur; | ||
142 | |||
143 | if (!node->dev_id) | ||
144 | printk(KERN_INFO "%s: Warning: dev_id of %s is zero\n", | ||
145 | __FUNCTION__, node->devname); | ||
146 | |||
147 | local_irq_save(flags); | ||
148 | |||
149 | cur = *list; | ||
150 | |||
151 | while (cur) { | ||
152 | list = &cur->next; | ||
153 | cur = cur->next; | ||
154 | } | ||
155 | |||
156 | node->next = cur; | ||
157 | *list = node; | ||
158 | |||
159 | local_irq_restore(flags); | ||
160 | } | 112 | } |
161 | 113 | ||
162 | void M68360_delete_irq(irq_node_t **list, void *dev_id) | 114 | void enable_vector(unsigned int irq) |
163 | { | 115 | { |
164 | unsigned long flags; | 116 | pquicc->intr_cimr |= (1 << irq); |
165 | irq_node_t *node; | ||
166 | |||
167 | local_irq_save(flags); | ||
168 | |||
169 | for (node = *list; node; list = &node->next, node = *list) { | ||
170 | if (node->dev_id == dev_id) { | ||
171 | *list = node->next; | ||
172 | /* Mark it as free. */ | ||
173 | node->handler = NULL; | ||
174 | local_irq_restore(flags); | ||
175 | return; | ||
176 | } | ||
177 | } | ||
178 | local_irq_restore(flags); | ||
179 | printk (KERN_INFO "%s: tried to remove invalid irq\n", __FUNCTION__); | ||
180 | } | 117 | } |
181 | #endif | ||
182 | 118 | ||
183 | int request_irq( | 119 | void disable_vector(unsigned int irq) |
184 | unsigned int irq, | ||
185 | irqreturn_t (*handler)(int, void *, struct pt_regs *), | ||
186 | unsigned long flags, | ||
187 | const char *devname, | ||
188 | void *dev_id) | ||
189 | { | 120 | { |
190 | int mask = (1<<irq); | 121 | pquicc->intr_cimr &= ~(1 << irq); |
191 | |||
192 | irq += (CPM_VECTOR_BASE<<4); | ||
193 | |||
194 | if (irq >= INTERNAL_IRQS) { | ||
195 | printk (KERN_ERR "%s: Unknown IRQ %d from %s\n", __FUNCTION__, irq, devname); | ||
196 | return -ENXIO; | ||
197 | } | ||
198 | |||
199 | if (!(int_irq_list[irq].flags & IRQ_FLG_STD)) { | ||
200 | if (int_irq_list[irq].flags & IRQ_FLG_LOCK) { | ||
201 | printk(KERN_ERR "%s: IRQ %d from %s is not replaceable\n", | ||
202 | __FUNCTION__, irq, int_irq_list[irq].devname); | ||
203 | return -EBUSY; | ||
204 | } | ||
205 | if (flags & IRQ_FLG_REPLACE) { | ||
206 | printk(KERN_ERR "%s: %s can't replace IRQ %d from %s\n", | ||
207 | __FUNCTION__, devname, irq, int_irq_list[irq].devname); | ||
208 | return -EBUSY; | ||
209 | } | ||
210 | } | ||
211 | int_irq_list[irq].handler = handler; | ||
212 | int_irq_list[irq].flags = flags; | ||
213 | int_irq_list[irq].dev_id = dev_id; | ||
214 | int_irq_list[irq].devname = devname; | ||
215 | |||
216 | /* enable in the CIMR */ | ||
217 | if (!int_irq_ablecount[irq]) | ||
218 | pquicc->intr_cimr |= mask; | ||
219 | /* *(volatile unsigned long *)0xfffff304 &= ~(1<<irq); */ | ||
220 | |||
221 | return 0; | ||
222 | } | 122 | } |
223 | 123 | ||
224 | EXPORT_SYMBOL(request_irq); | 124 | void ack_vector(unsigned int irq) |
225 | |||
226 | void free_irq(unsigned int irq, void *dev_id) | ||
227 | { | 125 | { |
228 | if (irq >= INTERNAL_IRQS) { | 126 | pquicc->intr_cisr = (1 << irq); |
229 | printk (KERN_ERR "%s: Unknown IRQ %d\n", __FUNCTION__, irq); | ||
230 | return; | ||
231 | } | ||
232 | |||
233 | if (int_irq_list[irq].dev_id != dev_id) | ||
234 | printk(KERN_INFO "%s: removing probably wrong IRQ %d from %s\n", | ||
235 | __FUNCTION__, irq, int_irq_list[irq].devname); | ||
236 | int_irq_list[irq].handler = NULL; | ||
237 | int_irq_list[irq].flags = IRQ_FLG_STD; | ||
238 | int_irq_list[irq].dev_id = NULL; | ||
239 | int_irq_list[irq].devname = NULL; | ||
240 | |||
241 | *(volatile unsigned long *)0xfffff304 |= 1<<irq; | ||
242 | } | 127 | } |
243 | 128 | ||
244 | EXPORT_SYMBOL(free_irq); | ||
245 | |||
246 | #if 0 | ||
247 | /* | ||
248 | * Enable/disable a particular machine specific interrupt source. | ||
249 | * Note that this may affect other interrupts in case of a shared interrupt. | ||
250 | * This function should only be called for a _very_ short time to change some | ||
251 | * internal data, that may not be changed by the interrupt at the same time. | ||
252 | * int_(enable|disable)_irq calls may also be nested. | ||
253 | */ | ||
254 | void M68360_enable_irq(unsigned int irq) | ||
255 | { | ||
256 | if (irq >= INTERNAL_IRQS) { | ||
257 | printk(KERN_ERR "%s: Unknown IRQ %d\n", __FUNCTION__, irq); | ||
258 | return; | ||
259 | } | ||
260 | |||
261 | if (--int_irq_ablecount[irq]) | ||
262 | return; | ||
263 | |||
264 | /* enable the interrupt */ | ||
265 | *(volatile unsigned long *)0xfffff304 &= ~(1<<irq); | ||
266 | } | ||
267 | |||
268 | void M68360_disable_irq(unsigned int irq) | ||
269 | { | ||
270 | if (irq >= INTERNAL_IRQS) { | ||
271 | printk(KERN_ERR "%s: Unknown IRQ %d\n", __FUNCTION__, irq); | ||
272 | return; | ||
273 | } | ||
274 | |||
275 | if (int_irq_ablecount[irq]++) | ||
276 | return; | ||
277 | |||
278 | /* disable the interrupt */ | ||
279 | *(volatile unsigned long *)0xfffff304 |= 1<<irq; | ||
280 | } | ||
281 | #endif | ||
282 | |||
283 | int show_interrupts(struct seq_file *p, void *v) | ||
284 | { | ||
285 | int i = *(loff_t *) v; | ||
286 | |||
287 | if (i < NR_IRQS) { | ||
288 | if (int_irq_list[i].devname) { | ||
289 | seq_printf(p, "%3d: %10u ", i, kstat_cpu(0).irqs[i]); | ||
290 | if (int_irq_list[i].flags & IRQ_FLG_LOCK) | ||
291 | seq_printf(p, "L "); | ||
292 | else | ||
293 | seq_printf(p, " "); | ||
294 | seq_printf(p, "%s\n", int_irq_list[i].devname); | ||
295 | } | ||
296 | } | ||
297 | if (i == NR_IRQS) | ||
298 | seq_printf(p, " : %10u spurious\n", num_spurious); | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | /* The 68k family did not have a good way to determine the source | ||
304 | * of interrupts until later in the family. The EC000 core does | ||
305 | * not provide the vector number on the stack, we vector everything | ||
306 | * into one vector and look in the blasted mask register... | ||
307 | * This code is designed to be fast, almost constant time, not clean! | ||
308 | */ | ||
309 | void process_int(int vec, struct pt_regs *fp) | ||
310 | { | ||
311 | int irq; | ||
312 | int mask; | ||
313 | |||
314 | /* unsigned long pend = *(volatile unsigned long *)0xfffff30c; */ | ||
315 | |||
316 | /* irq = vec + (CPM_VECTOR_BASE<<4); */ | ||
317 | irq = vec; | ||
318 | |||
319 | /* unsigned long pend = *(volatile unsigned long *)pquicc->intr_cipr; */ | ||
320 | |||
321 | /* Bugger all that weirdness. For the moment, I seem to know where I came from; | ||
322 | * vec is passed from a specific ISR, so I'll use it. */ | ||
323 | |||
324 | if (int_irq_list[irq].handler) { | ||
325 | int_irq_list[irq].handler(irq , int_irq_list[irq].dev_id, fp); | ||
326 | kstat_cpu(0).irqs[irq]++; | ||
327 | pquicc->intr_cisr = (1 << vec); /* indicate that irq has been serviced */ | ||
328 | } else { | ||
329 | printk(KERN_ERR "unregistered interrupt %d!\nTurning it off in the CIMR...\n", irq); | ||
330 | /* *(volatile unsigned long *)0xfffff304 |= mask; */ | ||
331 | pquicc->intr_cimr &= ~(1 << vec); | ||
332 | num_spurious += 1; | ||
333 | } | ||
334 | return(IRQ_HANDLED); | ||
335 | } | ||