]>
git.ipfire.org Git - people/ms/u-boot.git/blob - cpu/leon3/interrupts.c
3 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
6 * Detlev Zundel, DENX Software Engineering, dzu@denx.de
9 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
12 * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
14 * See file CREDITS for list of people who contributed to this
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
33 #include <asm/stack.h>
36 #include <asm/processor.h>
43 /* 15 normal irqs and a non maskable interrupt */
47 interrupt_handler_t
*handler
;
52 extern ambapp_dev_irqmp
*irqmp
;
53 extern ambapp_dev_gptimer
*gptimer
;
55 static struct irq_action irq_handlers
[NR_IRQS
] = { {0}, };
56 static int spurious_irq_cnt
= 0;
57 static int spurious_irq
= 0;
59 static inline unsigned int irqmp_get_irqmask(unsigned int irq
)
61 if ((irq
< 0) || (irq
>= NR_IRQS
)) {
69 static void leon3_ic_disable(unsigned int irq
)
71 unsigned int mask
, pil
;
77 /* get mask of interrupt */
78 mask
= irqmp_get_irqmask(irq
);
81 irqmp
->cpu_mask
[0] = SPARC_NOCACHE_READ(&irqmp
->cpu_mask
[0]) & (~mask
);
86 static void leon3_ic_enable(unsigned int irq
)
88 unsigned int mask
, pil
;
94 /* get mask of interrupt */
95 mask
= irqmp_get_irqmask(irq
);
98 irqmp
->cpu_mask
[0] = SPARC_NOCACHE_READ(&irqmp
->cpu_mask
[0]) | mask
;
104 void handler_irq(int irq
, struct pt_regs
*regs
)
106 if (irq_handlers
[irq
].handler
) {
107 if (((unsigned int)irq_handlers
[irq
].handler
> CONFIG_SYS_RAM_END
) ||
108 ((unsigned int)irq_handlers
[irq
].handler
< CONFIG_SYS_RAM_BASE
)
110 printf("handler_irq: bad handler: %x, irq number %d\n",
111 (unsigned int)irq_handlers
[irq
].handler
, irq
);
114 irq_handlers
[irq
].handler(irq_handlers
[irq
].arg
);
115 irq_handlers
[irq
].count
++;
122 void leon3_force_int(int irq
)
124 if (!irqmp
|| (irq
>= NR_IRQS
) || (irq
< 0))
126 printf("Forcing interrupt %d\n", irq
);
128 irqmp
->iforce
= SPARC_NOCACHE_READ(&irqmp
->iforce
) | (1 << irq
);
131 /****************************************************************************/
133 int interrupt_init_cpu(void)
139 /****************************************************************************/
141 /* Handle Timer 0 IRQ */
142 void timer_interrupt_cpu(void *arg
)
144 gptimer
->e
[0].ctrl
= (LEON3_GPTIMER_EN
|
146 LEON3_GPTIMER_LD
| LEON3_GPTIMER_IRQEN
);
147 /* nothing to do here */
151 /****************************************************************************/
154 * Install and free a interrupt handler.
157 void irq_install_handler(int irq
, interrupt_handler_t
* handler
, void *arg
)
159 if (irq
< 0 || irq
>= NR_IRQS
) {
160 printf("irq_install_handler: bad irq number %d\n", irq
);
164 if (irq_handlers
[irq
].handler
!= NULL
)
165 printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
166 (ulong
) handler
, (ulong
) irq_handlers
[irq
].handler
);
168 if (((unsigned int)handler
> CONFIG_SYS_RAM_END
) ||
169 ((unsigned int)handler
< CONFIG_SYS_RAM_BASE
)
171 printf("irq_install_handler: bad handler: %x, irq number %d\n",
172 (unsigned int)handler
, irq
);
175 irq_handlers
[irq
].handler
= handler
;
176 irq_handlers
[irq
].arg
= arg
;
178 /* enable irq on IRQMP hardware */
179 leon3_ic_enable(irq
);
183 void irq_free_handler(int irq
)
185 if (irq
< 0 || irq
>= NR_IRQS
) {
186 printf("irq_free_handler: bad irq number %d\n", irq
);
190 /* disable irq on IRQMP hardware */
191 leon3_ic_disable(irq
);
193 irq_handlers
[irq
].handler
= NULL
;
194 irq_handlers
[irq
].arg
= NULL
;
197 /****************************************************************************/
199 #if defined(CONFIG_CMD_IRQ)
200 void do_irqinfo(cmd_tbl_t
* cmdtp
, bd_t
* bd
, int flag
, int argc
, char *argv
[])
203 unsigned int pil
= get_pil();
204 printf("PIL level: %u\n\r", pil
);
205 printf("Spurious IRQ: %u, last unknown IRQ: %d\n",
206 spurious_irq_cnt
, spurious_irq
);
208 puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n");
210 for (irq
= 0; irq
< NR_IRQS
; irq
++) {
211 if (irq_handlers
[irq
].handler
!= NULL
) {
212 printf("%02d %08lx %08lx %ld\n", irq
,
213 (unsigned int)irq_handlers
[irq
].handler
,
214 (unsigned int)irq_handlers
[irq
].arg
,
215 irq_handlers
[irq
].count
);