blob: 886f405156229a730667660a5ca848f9bcfeeaf8 [file] [log] [blame]
wdenkf780aa22002-09-18 19:21:21 +00001/*
2 * (C) Copyright 2000-2002
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * (C) Copyright 2002 (440 port)
6 * Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com
7 *
wdenkba56f622004-02-06 23:19:44 +00008 * (C) Copyright 2003 (440GX port)
9 * Travis B. Sawyer, Sandburst Corporation, tsawyer@sandburst.com
10 *
wdenkf780aa22002-09-18 19:21:21 +000011 * See file CREDITS for list of people who contributed to this
12 * project.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 * MA 02111-1307 USA
28 */
29
30#include <common.h>
31#include <watchdog.h>
32#include <command.h>
wdenkf780aa22002-09-18 19:21:21 +000033#include <asm/processor.h>
34#include <ppc4xx.h>
35#include <ppc_asm.tmpl>
36#include <commproc.h>
37#include "vecnum.h"
38
Wolfgang Denkd87080b2006-03-31 18:32:53 +020039DECLARE_GLOBAL_DATA_PTR;
40
wdenkf780aa22002-09-18 19:21:21 +000041/****************************************************************************/
42
wdenkf780aa22002-09-18 19:21:21 +000043/*
44 * CPM interrupt vector functions.
45 */
46struct irq_action {
47 interrupt_handler_t *handler;
48 void *arg;
49 int count;
50};
51
52static struct irq_action irq_vecs[32];
Marian Balakowicz6c5879f2006-06-30 16:30:46 +020053void uic0_interrupt( void * parms); /* UIC0 handler */
wdenkf780aa22002-09-18 19:21:21 +000054
55#if defined(CONFIG_440)
56static struct irq_action irq_vecs1[32]; /* For UIC1 */
57
58void uic1_interrupt( void * parms); /* UIC1 handler */
wdenkba56f622004-02-06 23:19:44 +000059
Marian Balakowicz6c5879f2006-06-30 16:30:46 +020060#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
wdenkba56f622004-02-06 23:19:44 +000061static struct irq_action irq_vecs2[32]; /* For UIC2 */
wdenkba56f622004-02-06 23:19:44 +000062void uic2_interrupt( void * parms); /* UIC2 handler */
Marian Balakowicz6c5879f2006-06-30 16:30:46 +020063#endif /* CONFIG_440GX CONFIG_440SPE */
64
65#if defined(CONFIG_440SPE)
66static struct irq_action irq_vecs3[32]; /* For UIC3 */
67void uic3_interrupt( void * parms); /* UIC3 handler */
68#endif /* CONFIG_440SPE */
wdenkba56f622004-02-06 23:19:44 +000069
70#endif /* CONFIG_440 */
wdenkf780aa22002-09-18 19:21:21 +000071
72/****************************************************************************/
wdenkf780aa22002-09-18 19:21:21 +000073#if defined(CONFIG_440)
74
75/* SPRN changed in 440 */
76static __inline__ void set_evpr(unsigned long val)
77{
78 asm volatile("mtspr 0x03f,%0" : : "r" (val));
79}
80
81#else /* !defined(CONFIG_440) */
82
wdenkf780aa22002-09-18 19:21:21 +000083static __inline__ void set_pit(unsigned long val)
84{
85 asm volatile("mtpit %0" : : "r" (val));
86}
87
88
89static __inline__ void set_tcr(unsigned long val)
90{
91 asm volatile("mttcr %0" : : "r" (val));
92}
93
94
95static __inline__ void set_evpr(unsigned long val)
96{
97 asm volatile("mtevpr %0" : : "r" (val));
98}
99#endif /* defined(CONFIG_440 */
100
wdenkf780aa22002-09-18 19:21:21 +0000101/****************************************************************************/
102
wdenka8c7c702003-12-06 19:49:23 +0000103int interrupt_init_cpu (unsigned *decrementer_count)
wdenkf780aa22002-09-18 19:21:21 +0000104{
wdenkf780aa22002-09-18 19:21:21 +0000105 int vec;
106 unsigned long val;
107
wdenka8c7c702003-12-06 19:49:23 +0000108 /* decrementer is automatically reloaded */
109 *decrementer_count = 0;
wdenkd4ca31c2004-01-02 14:00:00 +0000110
wdenkf780aa22002-09-18 19:21:21 +0000111 /*
112 * Mark all irqs as free
113 */
114 for (vec=0; vec<32; vec++) {
115 irq_vecs[vec].handler = NULL;
116 irq_vecs[vec].arg = NULL;
117 irq_vecs[vec].count = 0;
118#if defined(CONFIG_440)
119 irq_vecs1[vec].handler = NULL;
120 irq_vecs1[vec].arg = NULL;
121 irq_vecs1[vec].count = 0;
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200122#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
wdenkba56f622004-02-06 23:19:44 +0000123 irq_vecs2[vec].handler = NULL;
124 irq_vecs2[vec].arg = NULL;
125 irq_vecs2[vec].count = 0;
Stefan Roese846b0dd2005-08-08 12:42:22 +0200126#endif /* CONFIG_440GX */
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200127#if defined(CONFIG_440SPE)
128 irq_vecs3[vec].handler = NULL;
129 irq_vecs3[vec].arg = NULL;
130 irq_vecs3[vec].count = 0;
131#endif /* CONFIG_440SPE */
wdenkf780aa22002-09-18 19:21:21 +0000132#endif
133 }
134
135#ifdef CONFIG_4xx
136 /*
137 * Init PIT
138 */
139#if defined(CONFIG_440)
140 val = mfspr( tcr );
141 val &= (~0x04400000); /* clear DIS & ARE */
142 mtspr( tcr, val );
143 mtspr( dec, 0 ); /* Prevent exception after TSR clear*/
144 mtspr( decar, 0 ); /* clear reload */
145 mtspr( tsr, 0x08000000 ); /* clear DEC status */
stroese68e02362005-04-07 05:32:44 +0000146 val = gd->bd->bi_intfreq/1000; /* 1 msec */
wdenkf780aa22002-09-18 19:21:21 +0000147 mtspr( decar, val ); /* Set auto-reload value */
148 mtspr( dec, val ); /* Set inital val */
149#else
150 set_pit(gd->bd->bi_intfreq / 1000);
151#endif
152#endif /* CONFIG_4xx */
153
154#ifdef CONFIG_ADCIOP
155 /*
156 * Init PIT
157 */
158 set_pit(66000);
159#endif
160
161 /*
162 * Enable PIT
163 */
164 val = mfspr(tcr);
165 val |= 0x04400000;
166 mtspr(tcr, val);
167
168 /*
169 * Set EVPR to 0
170 */
171 set_evpr(0x00000000);
172
173#if defined(CONFIG_440)
Stefan Roese846b0dd2005-08-08 12:42:22 +0200174#if !defined(CONFIG_440GX)
wdenkf780aa22002-09-18 19:21:21 +0000175 /* Install the UIC1 handlers */
176 irq_install_handler(VECNUM_UIC1NC, uic1_interrupt, 0);
177 irq_install_handler(VECNUM_UIC1C, uic1_interrupt, 0);
178#endif
wdenkba56f622004-02-06 23:19:44 +0000179#endif
180
Stefan Roese846b0dd2005-08-08 12:42:22 +0200181#if defined(CONFIG_440GX)
wdenkaaf224a2004-03-14 15:20:55 +0000182 /* Take the GX out of compatibility mode
183 * Travis Sawyer, 9 Mar 2004
184 * NOTE: 440gx user manual inconsistency here
185 * Compatibility mode and Ethernet Clock select are not
186 * correct in the manual
187 */
188 mfsdr(sdr_mfr, val);
189 val &= ~0x10000000;
190 mtsdr(sdr_mfr,val);
191
wdenkba56f622004-02-06 23:19:44 +0000192 /* Enable UIC interrupts via UIC Base Enable Register */
wdenkaaf224a2004-03-14 15:20:55 +0000193 mtdcr(uicb0sr, UICB0_ALL);
194 mtdcr(uicb0er, 0x54000000);
195 /* None are critical */
196 mtdcr(uicb0cr, 0);
wdenkba56f622004-02-06 23:19:44 +0000197#endif
wdenkf780aa22002-09-18 19:21:21 +0000198
199 return (0);
200}
201
202/****************************************************************************/
203
204/*
205 * Handle external interrupts
206 */
Stefan Roese846b0dd2005-08-08 12:42:22 +0200207#if defined(CONFIG_440GX)
wdenkba56f622004-02-06 23:19:44 +0000208void external_interrupt(struct pt_regs *regs)
209{
210 ulong uic_msr;
211
212 /*
213 * Read masked interrupt status register to determine interrupt source
214 */
215 /* 440 GX uses base uic register */
216 uic_msr = mfdcr(uicb0msr);
217
wdenkaaf224a2004-03-14 15:20:55 +0000218 if ( (UICB0_UIC0CI & uic_msr) || (UICB0_UIC0NCI & uic_msr) )
219 uic0_interrupt(0);
wdenkba56f622004-02-06 23:19:44 +0000220
wdenkaaf224a2004-03-14 15:20:55 +0000221 if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
222 uic1_interrupt(0);
223
224 if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
225 uic2_interrupt(0);
226
227 mtdcr(uicb0sr, uic_msr);
wdenkba56f622004-02-06 23:19:44 +0000228
229 return;
230
Stefan Roese846b0dd2005-08-08 12:42:22 +0200231} /* external_interrupt CONFIG_440GX */
wdenkba56f622004-02-06 23:19:44 +0000232
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200233#elif defined(CONFIG_440SPE)
234void external_interrupt(struct pt_regs *regs)
235{
236 ulong uic_msr;
237
238 /*
239 * Read masked interrupt status register to determine interrupt source
240 */
241 /* 440 SPe uses base uic register */
242 uic_msr = mfdcr(uic0msr);
243
244 if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
245 uic1_interrupt(0);
246
247 if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
248 uic2_interrupt(0);
249
250 if ( (UICB0_UIC3CI & uic_msr) || (UICB0_UIC3NCI & uic_msr) )
251 uic3_interrupt(0);
252
253 if (uic_msr & ~(UICB0_ALL))
254 uic0_interrupt(0);
255
256 mtdcr(uic0sr, uic_msr);
257
258 return;
259} /* external_interrupt CONFIG_440SPE */
260
wdenkba56f622004-02-06 23:19:44 +0000261#else
262
wdenkf780aa22002-09-18 19:21:21 +0000263void external_interrupt(struct pt_regs *regs)
264{
265 ulong uic_msr;
266 ulong msr_shift;
267 int vec;
268
269 /*
270 * Read masked interrupt status register to determine interrupt source
271 */
272 uic_msr = mfdcr(uicmsr);
273 msr_shift = uic_msr;
274 vec = 0;
275
276 while (msr_shift != 0) {
277 if (msr_shift & 0x80000000) {
278 /*
279 * Increment irq counter (for debug purpose only)
280 */
281 irq_vecs[vec].count++;
282
283 if (irq_vecs[vec].handler != NULL) {
284 /* call isr */
285 (*irq_vecs[vec].handler)(irq_vecs[vec].arg);
286 } else {
287 mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> vec));
288 printf ("Masking bogus interrupt vector 0x%x\n", vec);
289 }
290
291 /*
292 * After servicing the interrupt, we have to remove the status indicator.
293 */
294 mtdcr(uicsr, (0x80000000 >> vec));
295 }
296
297 /*
298 * Shift msr to next position and increment vector
299 */
300 msr_shift <<= 1;
301 vec++;
302 }
303}
wdenkba56f622004-02-06 23:19:44 +0000304#endif
305
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200306#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
wdenkba56f622004-02-06 23:19:44 +0000307/* Handler for UIC0 interrupt */
308void uic0_interrupt( void * parms)
309{
310 ulong uic_msr;
311 ulong msr_shift;
312 int vec;
313
314 /*
315 * Read masked interrupt status register to determine interrupt source
316 */
317 uic_msr = mfdcr(uicmsr);
318 msr_shift = uic_msr;
319 vec = 0;
320
321 while (msr_shift != 0) {
322 if (msr_shift & 0x80000000) {
323 /*
324 * Increment irq counter (for debug purpose only)
325 */
326 irq_vecs[vec].count++;
327
328 if (irq_vecs[vec].handler != NULL) {
329 /* call isr */
330 (*irq_vecs[vec].handler)(irq_vecs[vec].arg);
331 } else {
332 mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> vec));
333 printf ("Masking bogus interrupt vector (uic0) 0x%x\n", vec);
334 }
335
336 /*
337 * After servicing the interrupt, we have to remove the status indicator.
338 */
339 mtdcr(uicsr, (0x80000000 >> vec));
340 }
341
342 /*
343 * Shift msr to next position and increment vector
344 */
345 msr_shift <<= 1;
346 vec++;
347 }
348}
349
Stefan Roese846b0dd2005-08-08 12:42:22 +0200350#endif /* CONFIG_440GX */
wdenkf780aa22002-09-18 19:21:21 +0000351
352#if defined(CONFIG_440)
353/* Handler for UIC1 interrupt */
354void uic1_interrupt( void * parms)
355{
356 ulong uic1_msr;
357 ulong msr_shift;
358 int vec;
359
360 /*
361 * Read masked interrupt status register to determine interrupt source
362 */
363 uic1_msr = mfdcr(uic1msr);
364 msr_shift = uic1_msr;
365 vec = 0;
366
367 while (msr_shift != 0) {
368 if (msr_shift & 0x80000000) {
369 /*
370 * Increment irq counter (for debug purpose only)
371 */
372 irq_vecs1[vec].count++;
373
374 if (irq_vecs1[vec].handler != NULL) {
375 /* call isr */
376 (*irq_vecs1[vec].handler)(irq_vecs1[vec].arg);
377 } else {
378 mtdcr(uic1er, mfdcr(uic1er) & ~(0x80000000 >> vec));
379 printf ("Masking bogus interrupt vector (uic1) 0x%x\n", vec);
380 }
381
382 /*
383 * After servicing the interrupt, we have to remove the status indicator.
384 */
385 mtdcr(uic1sr, (0x80000000 >> vec));
386 }
387
388 /*
389 * Shift msr to next position and increment vector
390 */
391 msr_shift <<= 1;
392 vec++;
393 }
394}
395#endif /* defined(CONFIG_440) */
396
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200397#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
398/* Handler for UIC2 interrupt */
wdenkba56f622004-02-06 23:19:44 +0000399void uic2_interrupt( void * parms)
400{
401 ulong uic2_msr;
402 ulong msr_shift;
403 int vec;
404
405 /*
406 * Read masked interrupt status register to determine interrupt source
407 */
408 uic2_msr = mfdcr(uic2msr);
409 msr_shift = uic2_msr;
410 vec = 0;
411
412 while (msr_shift != 0) {
413 if (msr_shift & 0x80000000) {
414 /*
415 * Increment irq counter (for debug purpose only)
416 */
417 irq_vecs2[vec].count++;
418
419 if (irq_vecs2[vec].handler != NULL) {
420 /* call isr */
421 (*irq_vecs2[vec].handler)(irq_vecs2[vec].arg);
422 } else {
423 mtdcr(uic2er, mfdcr(uic2er) & ~(0x80000000 >> vec));
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200424 printf ("Masking bogus interrupt vector (uic2) 0x%x\n", vec);
wdenkba56f622004-02-06 23:19:44 +0000425 }
426
427 /*
428 * After servicing the interrupt, we have to remove the status indicator.
429 */
430 mtdcr(uic2sr, (0x80000000 >> vec));
431 }
432
433 /*
434 * Shift msr to next position and increment vector
435 */
436 msr_shift <<= 1;
437 vec++;
438 }
439}
Stefan Roese846b0dd2005-08-08 12:42:22 +0200440#endif /* defined(CONFIG_440GX) */
wdenkba56f622004-02-06 23:19:44 +0000441
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200442#if defined(CONFIG_440SPE)
443/* Handler for UIC3 interrupt */
444void uic3_interrupt( void * parms)
445{
446 ulong uic3_msr;
447 ulong msr_shift;
448 int vec;
449
450 /*
451 * Read masked interrupt status register to determine interrupt source
452 */
453 uic3_msr = mfdcr(uic3msr);
454 msr_shift = uic3_msr;
455 vec = 0;
456
457 while (msr_shift != 0) {
458 if (msr_shift & 0x80000000) {
459 /*
460 * Increment irq counter (for debug purpose only)
461 */
462 irq_vecs3[vec].count++;
463
464 if (irq_vecs3[vec].handler != NULL) {
465 /* call isr */
466 (*irq_vecs3[vec].handler)(irq_vecs3[vec].arg);
467 } else {
468 mtdcr(uic3er, mfdcr(uic3er) & ~(0x80000000 >> vec));
469 printf ("Masking bogus interrupt vector (uic3) 0x%x\n", vec);
470 }
471
472 /*
473 * After servicing the interrupt, we have to remove the status indicator.
474 */
475 mtdcr(uic3sr, (0x80000000 >> vec));
476 }
477
478 /*
479 * Shift msr to next position and increment vector
480 */
481 msr_shift <<= 1;
482 vec++;
483 }
484}
485#endif /* defined(CONFIG_440SPE) */
486
wdenkf780aa22002-09-18 19:21:21 +0000487/****************************************************************************/
488
489/*
490 * Install and free a interrupt handler.
491 */
492
wdenkba56f622004-02-06 23:19:44 +0000493void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
wdenkf780aa22002-09-18 19:21:21 +0000494{
495 struct irq_action *irqa = irq_vecs;
wdenkba56f622004-02-06 23:19:44 +0000496 int i = vec;
wdenkf780aa22002-09-18 19:21:21 +0000497
498#if defined(CONFIG_440)
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200499#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
wdenkba56f622004-02-06 23:19:44 +0000500 if ((vec > 31) && (vec < 64)) {
501 i = vec - 32;
502 irqa = irq_vecs1;
503 } else if (vec > 63) {
504 i = vec - 64;
505 irqa = irq_vecs2;
506 }
Stefan Roese846b0dd2005-08-08 12:42:22 +0200507#else /* CONFIG_440GX */
wdenkf780aa22002-09-18 19:21:21 +0000508 if (vec > 31) {
509 i = vec - 32;
510 irqa = irq_vecs1;
511 }
Stefan Roese846b0dd2005-08-08 12:42:22 +0200512#endif /* CONFIG_440GX */
wdenkba56f622004-02-06 23:19:44 +0000513#endif /* CONFIG_440 */
wdenkf780aa22002-09-18 19:21:21 +0000514
Stefan Roesec157d8e2005-08-01 16:41:48 +0200515 /*
516 * print warning when replacing with a different irq vector
517 */
518 if ((irqa[i].handler != NULL) && (irqa[i].handler != handler)) {
wdenkf780aa22002-09-18 19:21:21 +0000519 printf ("Interrupt vector %d: handler 0x%x replacing 0x%x\n",
wdenkba56f622004-02-06 23:19:44 +0000520 vec, (uint) handler, (uint) irqa[i].handler);
wdenkf780aa22002-09-18 19:21:21 +0000521 }
522 irqa[i].handler = handler;
wdenkba56f622004-02-06 23:19:44 +0000523 irqa[i].arg = arg;
wdenkf780aa22002-09-18 19:21:21 +0000524
525#if defined(CONFIG_440)
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200526#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
wdenkba56f622004-02-06 23:19:44 +0000527 if ((vec > 31) && (vec < 64))
528 mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i));
529 else if (vec > 63)
530 mtdcr (uic2er, mfdcr (uic2er) | (0x80000000 >> i));
531 else
Stefan Roese846b0dd2005-08-08 12:42:22 +0200532#endif /* CONFIG_440GX */
wdenkba56f622004-02-06 23:19:44 +0000533 if (vec > 31)
534 mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i));
wdenkf780aa22002-09-18 19:21:21 +0000535 else
536#endif
wdenkba56f622004-02-06 23:19:44 +0000537 mtdcr (uicer, mfdcr (uicer) | (0x80000000 >> i));
wdenkf780aa22002-09-18 19:21:21 +0000538#if 0
539 printf ("Install interrupt for vector %d ==> %p\n", vec, handler);
540#endif
541}
542
wdenkba56f622004-02-06 23:19:44 +0000543void irq_free_handler (int vec)
wdenkf780aa22002-09-18 19:21:21 +0000544{
545 struct irq_action *irqa = irq_vecs;
wdenkba56f622004-02-06 23:19:44 +0000546 int i = vec;
wdenkf780aa22002-09-18 19:21:21 +0000547
548#if defined(CONFIG_440)
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200549#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
wdenkba56f622004-02-06 23:19:44 +0000550 if ((vec > 31) && (vec < 64)) {
551 irqa = irq_vecs1;
552 i = vec - 32;
553 } else if (vec > 63) {
554 irqa = irq_vecs2;
555 i = vec - 64;
556 }
Stefan Roese846b0dd2005-08-08 12:42:22 +0200557#endif /* CONFIG_440GX */
wdenkf780aa22002-09-18 19:21:21 +0000558 if (vec > 31) {
559 irqa = irq_vecs1;
560 i = vec - 32;
561 }
562#endif
563
564#if 0
565 printf ("Free interrupt for vector %d ==> %p\n",
566 vec, irq_vecs[vec].handler);
567#endif
568
569#if defined(CONFIG_440)
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200570#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
wdenkba56f622004-02-06 23:19:44 +0000571 if ((vec > 31) && (vec < 64))
572 mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i));
573 else if (vec > 63)
574 mtdcr (uic2er, mfdcr (uic2er) & ~(0x80000000 >> i));
575 else
Stefan Roese846b0dd2005-08-08 12:42:22 +0200576#endif /* CONFIG_440GX */
wdenkf780aa22002-09-18 19:21:21 +0000577 if (vec > 31)
wdenkba56f622004-02-06 23:19:44 +0000578 mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i));
wdenkf780aa22002-09-18 19:21:21 +0000579 else
580#endif
wdenkba56f622004-02-06 23:19:44 +0000581 mtdcr (uicer, mfdcr (uicer) & ~(0x80000000 >> i));
wdenkf780aa22002-09-18 19:21:21 +0000582
583 irqa[i].handler = NULL;
wdenkba56f622004-02-06 23:19:44 +0000584 irqa[i].arg = NULL;
wdenkf780aa22002-09-18 19:21:21 +0000585}
586
587/****************************************************************************/
588
wdenka8c7c702003-12-06 19:49:23 +0000589void timer_interrupt_cpu (struct pt_regs *regs)
wdenkf780aa22002-09-18 19:21:21 +0000590{
wdenka8c7c702003-12-06 19:49:23 +0000591 /* nothing to do here */
592 return;
wdenkf780aa22002-09-18 19:21:21 +0000593}
594
595/****************************************************************************/
596
wdenkf780aa22002-09-18 19:21:21 +0000597#if (CONFIG_COMMANDS & CFG_CMD_IRQ)
598
599/*******************************************************************************
600 *
601 * irqinfo - print information about PCI devices
602 *
603 */
604int
605do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
606{
607 int vec;
608
609 printf ("\nInterrupt-Information:\n");
610#if defined(CONFIG_440)
611 printf ("\nUIC 0\n");
612#endif
613 printf ("Nr Routine Arg Count\n");
614
615 for (vec=0; vec<32; vec++) {
616 if (irq_vecs[vec].handler != NULL) {
617 printf ("%02d %08lx %08lx %d\n",
618 vec,
619 (ulong)irq_vecs[vec].handler,
620 (ulong)irq_vecs[vec].arg,
621 irq_vecs[vec].count);
622 }
623 }
624
625#if defined(CONFIG_440)
626 printf ("\nUIC 1\n");
627 printf ("Nr Routine Arg Count\n");
628
wdenkba56f622004-02-06 23:19:44 +0000629 for (vec=0; vec<32; vec++) {
wdenkf780aa22002-09-18 19:21:21 +0000630 if (irq_vecs1[vec].handler != NULL)
631 printf ("%02d %08lx %08lx %d\n",
632 vec+31, (ulong)irq_vecs1[vec].handler,
633 (ulong)irq_vecs1[vec].arg, irq_vecs1[vec].count);
634 }
635 printf("\n");
636#endif
wdenkba56f622004-02-06 23:19:44 +0000637
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200638#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
wdenkba56f622004-02-06 23:19:44 +0000639 printf ("\nUIC 2\n");
640 printf ("Nr Routine Arg Count\n");
641
642 for (vec=0; vec<32; vec++) {
643 if (irq_vecs2[vec].handler != NULL)
644 printf ("%02d %08lx %08lx %d\n",
645 vec+63, (ulong)irq_vecs2[vec].handler,
646 (ulong)irq_vecs2[vec].arg, irq_vecs2[vec].count);
647 }
648 printf("\n");
649#endif
650
Marian Balakowicz6c5879f2006-06-30 16:30:46 +0200651#if defined(CONFIG_440SPE)
652 printf ("\nUIC 3\n");
653 printf ("Nr Routine Arg Count\n");
654
655 for (vec=0; vec<32; vec++) {
656 if (irq_vecs3[vec].handler != NULL)
657 printf ("%02d %08lx %08lx %d\n",
658 vec+63, (ulong)irq_vecs3[vec].handler,
659 (ulong)irq_vecs3[vec].arg, irq_vecs3[vec].count);
660 }
661 printf("\n");
662#endif
663
wdenkf780aa22002-09-18 19:21:21 +0000664 return 0;
665}
wdenkf780aa22002-09-18 19:21:21 +0000666#endif /* CONFIG_COMMANDS & CFG_CMD_IRQ */