1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <common.h>
25#include <mpc8xx.h>
26#include <mpc8xx_irq.h>
27#include <asm/processor.h>
28#include <commproc.h>
29
30
31
32
33
34
35struct interrupt_action {
36 interrupt_handler_t *handler;
37 void *arg;
38};
39
40static struct interrupt_action cpm_vecs[CPMVEC_NR];
41static struct interrupt_action irq_vecs[NR_IRQS];
42
43static void cpm_interrupt_init (void);
44static void cpm_interrupt (void *regs);
45
46
47
48int interrupt_init_cpu (unsigned *decrementer_count)
49{
50 volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
51
52 *decrementer_count = get_tbclk () / CONFIG_SYS_HZ;
53
54
55 immr->im_siu_conf.sc_simask = 0;
56
57
58 cpm_interrupt_init ();
59
60 return (0);
61}
62
63
64
65
66
67
68void external_interrupt (struct pt_regs *regs)
69{
70 volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
71 int irq;
72 ulong simask, newmask;
73 ulong vec, v_bit;
74
75
76
77
78
79 vec = immr->im_siu_conf.sc_sivec;
80 irq = vec >> 26;
81 v_bit = 0x80000000UL >> irq;
82
83
84
85
86 simask = immr->im_siu_conf.sc_simask;
87 newmask = simask & (~(0xFFFF0000 >> irq));
88 immr->im_siu_conf.sc_simask = newmask;
89
90 if (!(irq & 0x1)) {
91 ulong siel;
92
93
94
95
96 siel = immr->im_siu_conf.sc_siel;
97
98 if (siel & v_bit) {
99
100
101
102 immr->im_siu_conf.sc_sipend = v_bit;
103 }
104 }
105
106 if (irq_vecs[irq].handler != NULL) {
107 irq_vecs[irq].handler (irq_vecs[irq].arg);
108 } else {
109 printf ("\nBogus External Interrupt IRQ %d Vector %ld\n",
110 irq, vec);
111
112 simask &= ~v_bit;
113 }
114
115
116
117 immr->im_siu_conf.sc_simask = simask;
118}
119
120
121
122
123
124
125static void cpm_interrupt (void *regs)
126{
127 volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
128 uint vec;
129
130
131
132
133
134 immr->im_cpic.cpic_civr = 1;
135 vec = immr->im_cpic.cpic_civr;
136 vec >>= 11;
137
138 if (cpm_vecs[vec].handler != NULL) {
139 (*cpm_vecs[vec].handler) (cpm_vecs[vec].arg);
140 } else {
141 immr->im_cpic.cpic_cimr &= ~(1 << vec);
142 printf ("Masking bogus CPM interrupt vector 0x%x\n", vec);
143 }
144
145
146
147
148 immr->im_cpic.cpic_cisr |= (1 << vec);
149}
150
151
152
153
154
155
156
157static void cpm_error_interrupt (void *dummy)
158{
159}
160
161
162
163
164
165void irq_install_handler (int vec, interrupt_handler_t * handler,
166 void *arg)
167{
168 volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
169
170 if ((vec & CPMVEC_OFFSET) != 0) {
171
172 vec &= 0xffff;
173 if (cpm_vecs[vec].handler != NULL) {
174 printf ("CPM interrupt 0x%x replacing 0x%x\n",
175 (uint) handler,
176 (uint) cpm_vecs[vec].handler);
177 }
178 cpm_vecs[vec].handler = handler;
179 cpm_vecs[vec].arg = arg;
180 immr->im_cpic.cpic_cimr |= (1 << vec);
181#if 0
182 printf ("Install CPM interrupt for vector %d ==> %p\n",
183 vec, handler);
184#endif
185 } else {
186
187 if (irq_vecs[vec].handler != NULL) {
188 printf ("SIU interrupt %d 0x%x replacing 0x%x\n",
189 vec,
190 (uint) handler,
191 (uint) cpm_vecs[vec].handler);
192 }
193 irq_vecs[vec].handler = handler;
194 irq_vecs[vec].arg = arg;
195 immr->im_siu_conf.sc_simask |= 1 << (31 - vec);
196#if 0
197 printf ("Install SIU interrupt for vector %d ==> %p\n",
198 vec, handler);
199#endif
200 }
201}
202
203void irq_free_handler (int vec)
204{
205 volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
206
207 if ((vec & CPMVEC_OFFSET) != 0) {
208
209 vec &= 0xffff;
210#if 0
211 printf ("Free CPM interrupt for vector %d ==> %p\n",
212 vec, cpm_vecs[vec].handler);
213#endif
214 immr->im_cpic.cpic_cimr &= ~(1 << vec);
215 cpm_vecs[vec].handler = NULL;
216 cpm_vecs[vec].arg = NULL;
217 } else {
218
219#if 0
220 printf ("Free CPM interrupt for vector %d ==> %p\n",
221 vec, cpm_vecs[vec].handler);
222#endif
223 immr->im_siu_conf.sc_simask &= ~(1 << (31 - vec));
224 irq_vecs[vec].handler = NULL;
225 irq_vecs[vec].arg = NULL;
226 }
227}
228
229
230
231static void cpm_interrupt_init (void)
232{
233 volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
234
235
236
237
238
239 immr->im_cpic.cpic_cicr =
240 (CICR_SCD_SCC4 |
241 CICR_SCC_SCC3 |
242 CICR_SCB_SCC2 |
243 CICR_SCA_SCC1) | ((CPM_INTERRUPT / 2) << 13) | CICR_HP_MASK;
244
245 immr->im_cpic.cpic_cimr = 0;
246
247
248
249
250 irq_install_handler (CPMVEC_ERROR, cpm_error_interrupt, NULL);
251
252 immr->im_cpic.cpic_cicr |= CICR_IEN;
253
254
255
256
257 irq_install_handler (CPM_INTERRUPT, cpm_interrupt, NULL);
258}
259
260
261
262
263
264
265
266
267void timer_interrupt_cpu (struct pt_regs *regs)
268{
269 volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
270
271#if 0
272 printf ("*** Timer Interrupt *** ");
273#endif
274
275 immr->im_clkrstk.cark_plprcrk = KAPWR_KEY;
276 __asm__ ("nop");
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291 immr->im_clkrst.car_plprcr = immr->im_clkrst.car_plprcr;
292}
293
294
295