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/platform/5307 | |
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/platform/5307')
-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 |
4 files changed, 31 insertions, 321 deletions
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(); |