diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2007-08-02 10:36:02 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-08-26 21:16:53 -0400 |
commit | c87abd75b35e8f991ff8ff1510d6fb62612c61fa (patch) | |
tree | de68c4446c35337c47c17253d769bfeee92f80b3 /arch/mips/tx4927/common | |
parent | 8420fd00e88ef4f6082866aa151bc753b006b3b6 (diff) |
[MIPS] Cleanup TX39/TX49 irq code
Cleanup jmr3927, tx4927 and tx4938 irq codes, using common IRQ_CPU,
I8259 and IRQ_TXX9 irq routines.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/tx4927/common')
-rw-r--r-- | arch/mips/tx4927/common/tx4927_irq.c | 395 |
1 files changed, 10 insertions, 385 deletions
diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c index 00b0b975f349..0aabd57fdad2 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/tx4927/common/tx4927_irq.c | |||
@@ -23,398 +23,20 @@ | |||
23 | * with this program; if not, write to the Free Software Foundation, Inc., | 23 | * with this program; if not, write to the Free Software Foundation, Inc., |
24 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 24 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
25 | */ | 25 | */ |
26 | #include <linux/errno.h> | ||
27 | #include <linux/init.h> | 26 | #include <linux/init.h> |
28 | #include <linux/kernel_stat.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/signal.h> | ||
31 | #include <linux/sched.h> | ||
32 | #include <linux/types.h> | ||
33 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
34 | #include <linux/ioport.h> | 28 | #include <asm/irq_cpu.h> |
35 | #include <linux/timex.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/random.h> | ||
38 | #include <linux/irq.h> | ||
39 | #include <linux/bitops.h> | ||
40 | #include <asm/bootinfo.h> | ||
41 | #include <asm/io.h> | ||
42 | #include <asm/irq.h> | ||
43 | #include <asm/mipsregs.h> | 29 | #include <asm/mipsregs.h> |
44 | #include <asm/system.h> | ||
45 | #include <asm/tx4927/tx4927.h> | 30 | #include <asm/tx4927/tx4927.h> |
46 | #ifdef CONFIG_TOSHIBA_RBTX4927 | 31 | #ifdef CONFIG_TOSHIBA_RBTX4927 |
47 | #include <asm/tx4927/toshiba_rbtx4927.h> | 32 | #include <asm/tx4927/toshiba_rbtx4927.h> |
48 | #endif | 33 | #endif |
49 | 34 | ||
50 | /* | ||
51 | * DEBUG | ||
52 | */ | ||
53 | |||
54 | #undef TX4927_IRQ_DEBUG | ||
55 | |||
56 | #ifdef TX4927_IRQ_DEBUG | ||
57 | #define TX4927_IRQ_NONE 0x00000000 | ||
58 | |||
59 | #define TX4927_IRQ_INFO ( 1 << 0 ) | ||
60 | #define TX4927_IRQ_WARN ( 1 << 1 ) | ||
61 | #define TX4927_IRQ_EROR ( 1 << 2 ) | ||
62 | |||
63 | #define TX4927_IRQ_INIT ( 1 << 5 ) | ||
64 | #define TX4927_IRQ_NEST1 ( 1 << 6 ) | ||
65 | #define TX4927_IRQ_NEST2 ( 1 << 7 ) | ||
66 | #define TX4927_IRQ_NEST3 ( 1 << 8 ) | ||
67 | #define TX4927_IRQ_NEST4 ( 1 << 9 ) | ||
68 | |||
69 | #define TX4927_IRQ_CP0_INIT ( 1 << 10 ) | ||
70 | #define TX4927_IRQ_CP0_ENABLE ( 1 << 13 ) | ||
71 | #define TX4927_IRQ_CP0_DISABLE ( 1 << 14 ) | ||
72 | |||
73 | #define TX4927_IRQ_PIC_INIT ( 1 << 20 ) | ||
74 | #define TX4927_IRQ_PIC_ENABLE ( 1 << 23 ) | ||
75 | #define TX4927_IRQ_PIC_DISABLE ( 1 << 24 ) | ||
76 | |||
77 | #define TX4927_IRQ_ALL 0xffffffff | ||
78 | #endif | ||
79 | |||
80 | #ifdef TX4927_IRQ_DEBUG | ||
81 | static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE | ||
82 | | TX4927_IRQ_INFO | ||
83 | | TX4927_IRQ_WARN | TX4927_IRQ_EROR | ||
84 | // | TX4927_IRQ_CP0_INIT | ||
85 | // | TX4927_IRQ_CP0_ENABLE | ||
86 | // | TX4927_IRQ_CP0_ENDIRQ | ||
87 | // | TX4927_IRQ_PIC_INIT | ||
88 | // | TX4927_IRQ_PIC_ENABLE | ||
89 | // | TX4927_IRQ_PIC_DISABLE | ||
90 | // | TX4927_IRQ_INIT | ||
91 | // | TX4927_IRQ_NEST1 | ||
92 | // | TX4927_IRQ_NEST2 | ||
93 | // | TX4927_IRQ_NEST3 | ||
94 | // | TX4927_IRQ_NEST4 | ||
95 | ); | ||
96 | #endif | ||
97 | |||
98 | #ifdef TX4927_IRQ_DEBUG | ||
99 | #define TX4927_IRQ_DPRINTK(flag,str...) \ | ||
100 | if ( (tx4927_irq_debug_flag) & (flag) ) \ | ||
101 | { \ | ||
102 | char tmp[100]; \ | ||
103 | sprintf( tmp, str ); \ | ||
104 | printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ | ||
105 | } | ||
106 | #else | ||
107 | #define TX4927_IRQ_DPRINTK(flag,str...) | ||
108 | #endif | ||
109 | |||
110 | /* | ||
111 | * Forwad definitions for all pic's | ||
112 | */ | ||
113 | |||
114 | static void tx4927_irq_cp0_enable(unsigned int irq); | ||
115 | static void tx4927_irq_cp0_disable(unsigned int irq); | ||
116 | |||
117 | static void tx4927_irq_pic_enable(unsigned int irq); | ||
118 | static void tx4927_irq_pic_disable(unsigned int irq); | ||
119 | |||
120 | /* | ||
121 | * Kernel structs for all pic's | ||
122 | */ | ||
123 | |||
124 | #define TX4927_CP0_NAME "TX4927-CP0" | ||
125 | static struct irq_chip tx4927_irq_cp0_type = { | ||
126 | .name = TX4927_CP0_NAME, | ||
127 | .ack = tx4927_irq_cp0_disable, | ||
128 | .mask = tx4927_irq_cp0_disable, | ||
129 | .mask_ack = tx4927_irq_cp0_disable, | ||
130 | .unmask = tx4927_irq_cp0_enable, | ||
131 | }; | ||
132 | |||
133 | #define TX4927_PIC_NAME "TX4927-PIC" | ||
134 | static struct irq_chip tx4927_irq_pic_type = { | ||
135 | .name = TX4927_PIC_NAME, | ||
136 | .ack = tx4927_irq_pic_disable, | ||
137 | .mask = tx4927_irq_pic_disable, | ||
138 | .mask_ack = tx4927_irq_pic_disable, | ||
139 | .unmask = tx4927_irq_pic_enable, | ||
140 | }; | ||
141 | |||
142 | #define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } | ||
143 | static struct irqaction tx4927_irq_pic_action = | ||
144 | TX4927_PIC_ACTION(TX4927_PIC_NAME); | ||
145 | |||
146 | #define CCP0_STATUS 12 | ||
147 | #define CCP0_CAUSE 13 | ||
148 | |||
149 | /* | ||
150 | * Functions for cp0 | ||
151 | */ | ||
152 | |||
153 | #define tx4927_irq_cp0_mask(irq) ( 1 << ( irq-TX4927_IRQ_CP0_BEG+8 ) ) | ||
154 | |||
155 | static void | ||
156 | tx4927_irq_cp0_modify(unsigned cp0_reg, unsigned clr_bits, unsigned set_bits) | ||
157 | { | ||
158 | unsigned long val = 0; | ||
159 | |||
160 | switch (cp0_reg) { | ||
161 | case CCP0_STATUS: | ||
162 | val = read_c0_status(); | ||
163 | break; | ||
164 | |||
165 | case CCP0_CAUSE: | ||
166 | val = read_c0_cause(); | ||
167 | break; | ||
168 | |||
169 | } | ||
170 | |||
171 | val &= (~clr_bits); | ||
172 | val |= (set_bits); | ||
173 | |||
174 | switch (cp0_reg) { | ||
175 | case CCP0_STATUS:{ | ||
176 | write_c0_status(val); | ||
177 | break; | ||
178 | } | ||
179 | case CCP0_CAUSE:{ | ||
180 | write_c0_cause(val); | ||
181 | break; | ||
182 | } | ||
183 | } | ||
184 | } | ||
185 | |||
186 | static void __init tx4927_irq_cp0_init(void) | ||
187 | { | ||
188 | int i; | ||
189 | |||
190 | TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_INIT, "beg=%d end=%d\n", | ||
191 | TX4927_IRQ_CP0_BEG, TX4927_IRQ_CP0_END); | ||
192 | |||
193 | for (i = TX4927_IRQ_CP0_BEG; i <= TX4927_IRQ_CP0_END; i++) | ||
194 | set_irq_chip_and_handler(i, &tx4927_irq_cp0_type, | ||
195 | handle_level_irq); | ||
196 | } | ||
197 | |||
198 | static void tx4927_irq_cp0_enable(unsigned int irq) | ||
199 | { | ||
200 | TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENABLE, "irq=%d \n", irq); | ||
201 | |||
202 | tx4927_irq_cp0_modify(CCP0_STATUS, 0, tx4927_irq_cp0_mask(irq)); | ||
203 | } | ||
204 | |||
205 | static void tx4927_irq_cp0_disable(unsigned int irq) | ||
206 | { | ||
207 | TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_DISABLE, "irq=%d \n", irq); | ||
208 | |||
209 | tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0); | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * Functions for pic | ||
214 | */ | ||
215 | u32 tx4927_irq_pic_addr(int irq) | ||
216 | { | ||
217 | /* MVMCP -- need to formulize this */ | ||
218 | irq -= TX4927_IRQ_PIC_BEG; | ||
219 | switch (irq) { | ||
220 | case 17: | ||
221 | case 16: | ||
222 | case 1: | ||
223 | case 0: | ||
224 | return (0xff1ff610); | ||
225 | |||
226 | case 19: | ||
227 | case 18: | ||
228 | case 3: | ||
229 | case 2: | ||
230 | return (0xff1ff614); | ||
231 | |||
232 | case 21: | ||
233 | case 20: | ||
234 | case 5: | ||
235 | case 4: | ||
236 | return (0xff1ff618); | ||
237 | |||
238 | case 23: | ||
239 | case 22: | ||
240 | case 7: | ||
241 | case 6: | ||
242 | return (0xff1ff61c); | ||
243 | |||
244 | case 25: | ||
245 | case 24: | ||
246 | case 9: | ||
247 | case 8: | ||
248 | return (0xff1ff620); | ||
249 | |||
250 | case 27: | ||
251 | case 26: | ||
252 | case 11: | ||
253 | case 10: | ||
254 | return (0xff1ff624); | ||
255 | |||
256 | case 29: | ||
257 | case 28: | ||
258 | case 13: | ||
259 | case 12: | ||
260 | return (0xff1ff628); | ||
261 | |||
262 | case 31: | ||
263 | case 30: | ||
264 | case 15: | ||
265 | case 14: | ||
266 | return (0xff1ff62c); | ||
267 | |||
268 | } | ||
269 | return (0); | ||
270 | } | ||
271 | |||
272 | u32 tx4927_irq_pic_mask(int irq) | ||
273 | { | ||
274 | /* MVMCP -- need to formulize this */ | ||
275 | irq -= TX4927_IRQ_PIC_BEG; | ||
276 | switch (irq) { | ||
277 | case 31: | ||
278 | case 29: | ||
279 | case 27: | ||
280 | case 25: | ||
281 | case 23: | ||
282 | case 21: | ||
283 | case 19: | ||
284 | case 17:{ | ||
285 | return (0x07000000); | ||
286 | } | ||
287 | case 30: | ||
288 | case 28: | ||
289 | case 26: | ||
290 | case 24: | ||
291 | case 22: | ||
292 | case 20: | ||
293 | case 18: | ||
294 | case 16:{ | ||
295 | return (0x00070000); | ||
296 | } | ||
297 | case 15: | ||
298 | case 13: | ||
299 | case 11: | ||
300 | case 9: | ||
301 | case 7: | ||
302 | case 5: | ||
303 | case 3: | ||
304 | case 1:{ | ||
305 | return (0x00000700); | ||
306 | } | ||
307 | case 14: | ||
308 | case 12: | ||
309 | case 10: | ||
310 | case 8: | ||
311 | case 6: | ||
312 | case 4: | ||
313 | case 2: | ||
314 | case 0:{ | ||
315 | return (0x00000007); | ||
316 | } | ||
317 | } | ||
318 | return (0x00000000); | ||
319 | } | ||
320 | |||
321 | static void tx4927_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, | ||
322 | unsigned set_bits) | ||
323 | { | ||
324 | unsigned long val = 0; | ||
325 | |||
326 | val = TX4927_RD(pic_reg); | ||
327 | val &= (~clr_bits); | ||
328 | val |= (set_bits); | ||
329 | TX4927_WR(pic_reg, val); | ||
330 | } | ||
331 | |||
332 | static void __init tx4927_irq_pic_init(void) | ||
333 | { | ||
334 | int i; | ||
335 | |||
336 | TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_INIT, "beg=%d end=%d\n", | ||
337 | TX4927_IRQ_PIC_BEG, TX4927_IRQ_PIC_END); | ||
338 | |||
339 | for (i = TX4927_IRQ_PIC_BEG; i <= TX4927_IRQ_PIC_END; i++) | ||
340 | set_irq_chip_and_handler(i, &tx4927_irq_pic_type, | ||
341 | handle_level_irq); | ||
342 | |||
343 | setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); | ||
344 | |||
345 | TX4927_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ | ||
346 | TX4927_WR(0xff1ff600, TX4927_RD(0xff1ff600) | 0x1); /* irq enable */ | ||
347 | } | ||
348 | |||
349 | static void tx4927_irq_pic_enable(unsigned int irq) | ||
350 | { | ||
351 | TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENABLE, "irq=%d\n", irq); | ||
352 | |||
353 | tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), 0, | ||
354 | tx4927_irq_pic_mask(irq)); | ||
355 | } | ||
356 | |||
357 | static void tx4927_irq_pic_disable(unsigned int irq) | ||
358 | { | ||
359 | TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_DISABLE, "irq=%d\n", irq); | ||
360 | |||
361 | tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), | ||
362 | tx4927_irq_pic_mask(irq), 0); | ||
363 | } | ||
364 | |||
365 | /* | ||
366 | * Main init functions | ||
367 | */ | ||
368 | void __init tx4927_irq_init(void) | 35 | void __init tx4927_irq_init(void) |
369 | { | 36 | { |
370 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); | 37 | mips_cpu_irq_init(); |
371 | 38 | txx9_irq_init(TX4927_IRC_REG); | |
372 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); | 39 | set_irq_chained_handler(TX4927_IRQ_NEST_PIC_ON_CP0, handle_simple_irq); |
373 | tx4927_irq_cp0_init(); | ||
374 | |||
375 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); | ||
376 | tx4927_irq_pic_init(); | ||
377 | |||
378 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); | ||
379 | } | ||
380 | |||
381 | static int tx4927_irq_nested(void) | ||
382 | { | ||
383 | int sw_irq = 0; | ||
384 | u32 level2; | ||
385 | |||
386 | TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "-\n"); | ||
387 | |||
388 | level2 = TX4927_RD(0xff1ff6a0); | ||
389 | TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=level2a=0x%x\n", level2); | ||
390 | |||
391 | if ((level2 & 0x10000) == 0) { | ||
392 | level2 &= 0x1f; | ||
393 | TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=level2b=0x%x\n", level2); | ||
394 | |||
395 | sw_irq = TX4927_IRQ_PIC_BEG + level2; | ||
396 | TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=sw_irq=%d\n", sw_irq); | ||
397 | |||
398 | if (sw_irq == 27) { | ||
399 | TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq-%d\n", | ||
400 | sw_irq); | ||
401 | |||
402 | #ifdef CONFIG_TOSHIBA_RBTX4927 | ||
403 | { | ||
404 | sw_irq = toshiba_rbtx4927_irq_nested(sw_irq); | ||
405 | } | ||
406 | #endif | ||
407 | |||
408 | TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq+%d\n", | ||
409 | sw_irq); | ||
410 | } | ||
411 | } | ||
412 | |||
413 | TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=sw_irq=%d\n", sw_irq); | ||
414 | |||
415 | TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "+\n"); | ||
416 | |||
417 | return (sw_irq); | ||
418 | } | 40 | } |
419 | 41 | ||
420 | asmlinkage void plat_irq_dispatch(void) | 42 | asmlinkage void plat_irq_dispatch(void) |
@@ -424,9 +46,12 @@ asmlinkage void plat_irq_dispatch(void) | |||
424 | if (pending & STATUSF_IP7) /* cpu timer */ | 46 | if (pending & STATUSF_IP7) /* cpu timer */ |
425 | do_IRQ(TX4927_IRQ_CPU_TIMER); | 47 | do_IRQ(TX4927_IRQ_CPU_TIMER); |
426 | else if (pending & STATUSF_IP2) { /* tx4927 pic */ | 48 | else if (pending & STATUSF_IP2) { /* tx4927 pic */ |
427 | unsigned int irq = tx4927_irq_nested(); | 49 | int irq = txx9_irq(); |
428 | 50 | #ifdef CONFIG_TOSHIBA_RBTX4927 | |
429 | if (unlikely(irq == 0)) { | 51 | if (irq == TX4927_IRQ_NEST_EXT_ON_PIC) |
52 | irq = toshiba_rbtx4927_irq_nested(irq); | ||
53 | #endif | ||
54 | if (unlikely(irq < 0)) { | ||
430 | spurious_interrupt(); | 55 | spurious_interrupt(); |
431 | return; | 56 | return; |
432 | } | 57 | } |