1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <asm/stack.h>
18#include <common.h>
19#include <asm/io.h>
20#include <asm/processor.h>
21#include <command.h>
22#include <asm/irq.h>
23
24#include <asm/leon.h>
25#include <ambapp.h>
26
27
28#define NR_IRQS 15
29
30struct irq_action {
31 interrupt_handler_t *handler;
32 void *arg;
33 unsigned int count;
34};
35
36extern ambapp_dev_irqmp *irqmp;
37extern ambapp_dev_gptimer *gptimer;
38
39static struct irq_action irq_handlers[NR_IRQS] = { {0}, };
40static int spurious_irq_cnt = 0;
41static int spurious_irq = 0;
42
43static inline unsigned int irqmp_get_irqmask(unsigned int irq)
44{
45 if ((irq < 0) || (irq >= NR_IRQS)) {
46 return 0;
47 } else {
48 return (1 << irq);
49 }
50
51}
52
53static void leon3_ic_disable(unsigned int irq)
54{
55 unsigned int mask, pil;
56 if (!irqmp)
57 return;
58
59 pil = intLock();
60
61
62 mask = irqmp_get_irqmask(irq);
63
64
65 irqmp->cpu_mask[0] = SPARC_NOCACHE_READ(&irqmp->cpu_mask[0]) & (~mask);
66
67 intUnlock(pil);
68}
69
70static void leon3_ic_enable(unsigned int irq)
71{
72 unsigned int mask, pil;
73 if (!irqmp)
74 return;
75
76 pil = intLock();
77
78
79 mask = irqmp_get_irqmask(irq);
80
81
82 irqmp->cpu_mask[0] = SPARC_NOCACHE_READ(&irqmp->cpu_mask[0]) | mask;
83
84 intUnlock(pil);
85
86}
87
88void handler_irq(int irq, struct pt_regs *regs)
89{
90 if (irq_handlers[irq].handler) {
91 if (((unsigned int)irq_handlers[irq].handler > CONFIG_SYS_RAM_END) ||
92 ((unsigned int)irq_handlers[irq].handler < CONFIG_SYS_RAM_BASE)
93 ) {
94 printf("handler_irq: bad handler: %x, irq number %d\n",
95 (unsigned int)irq_handlers[irq].handler, irq);
96 return;
97 }
98 irq_handlers[irq].handler(irq_handlers[irq].arg);
99 irq_handlers[irq].count++;
100 } else {
101 spurious_irq_cnt++;
102 spurious_irq = irq;
103 }
104}
105
106void leon3_force_int(int irq)
107{
108 if (!irqmp || (irq >= NR_IRQS) || (irq < 0))
109 return;
110 printf("Forcing interrupt %d\n", irq);
111
112 irqmp->iforce = SPARC_NOCACHE_READ(&irqmp->iforce) | (1 << irq);
113}
114
115
116
117int interrupt_init_cpu(void)
118{
119
120 return (0);
121}
122
123
124
125
126void timer_interrupt_cpu(void *arg)
127{
128 gptimer->e[0].ctrl = (LEON3_GPTIMER_EN |
129 LEON3_GPTIMER_RL |
130 LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
131
132 return;
133}
134
135
136
137
138
139
140
141void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg)
142{
143 if (irq < 0 || irq >= NR_IRQS) {
144 printf("irq_install_handler: bad irq number %d\n", irq);
145 return;
146 }
147
148 if (irq_handlers[irq].handler != NULL)
149 printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
150 (ulong) handler, (ulong) irq_handlers[irq].handler);
151
152 if (((unsigned int)handler > CONFIG_SYS_RAM_END) ||
153 ((unsigned int)handler < CONFIG_SYS_RAM_BASE)
154 ) {
155 printf("irq_install_handler: bad handler: %x, irq number %d\n",
156 (unsigned int)handler, irq);
157 return;
158 }
159 irq_handlers[irq].handler = handler;
160 irq_handlers[irq].arg = arg;
161
162
163 leon3_ic_enable(irq);
164
165}
166
167void irq_free_handler(int irq)
168{
169 if (irq < 0 || irq >= NR_IRQS) {
170 printf("irq_free_handler: bad irq number %d\n", irq);
171 return;
172 }
173
174
175 leon3_ic_disable(irq);
176
177 irq_handlers[irq].handler = NULL;
178 irq_handlers[irq].arg = NULL;
179}
180
181
182
183#if defined(CONFIG_CMD_IRQ)
184void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const argv[])
185{
186 int irq;
187 unsigned int pil = get_pil();
188 printf("PIL level: %u\n\r", pil);
189 printf("Spurious IRQ: %u, last unknown IRQ: %d\n",
190 spurious_irq_cnt, spurious_irq);
191
192 puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n");
193
194 for (irq = 0; irq < NR_IRQS; irq++) {
195 if (irq_handlers[irq].handler != NULL) {
196 printf("%02d %p %p %d\n", irq,
197 irq_handlers[irq].handler,
198 irq_handlers[irq].arg,
199 irq_handlers[irq].count);
200 }
201 }
202}
203#endif
204