This source file includes following definitions.
- amiga_init_INTS
- ami_int1
- ami_int2
- ami_int3
- ami_int4
- ami_int5
- ami_int6
- ami_int7
- ami_intcia
- amiga_add_isr
- amiga_get_irq_list
1
2
3
4
5
6
7
8
9
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
13
14 #include <asm/system.h>
15 #include <asm/irq.h>
16 #include <asm/traps.h>
17 #include <asm/amigahw.h>
18 #include <asm/amigaints.h>
19
20
21 static isr_node_t *ami_lists[NUM_AMIGA_SOURCES];
22
23 static const ushort ami_intena_vals[NUM_AMIGA_SOURCES] = {
24 IF_VERTB, IF_COPER, IF_AUD0, IF_AUD1, IF_AUD2, IF_AUD3, IF_BLIT,
25 IF_DSKSYN, IF_DSKBLK, IF_RBF, IF_TBE, IF_PORTS, IF_PORTS, IF_PORTS,
26 IF_PORTS, IF_PORTS, IF_EXTER, IF_EXTER, IF_EXTER, IF_EXTER, IF_EXTER,
27 IF_SOFT, IF_PORTS, IF_EXTER
28 };
29
30 struct ciadata
31 {
32 volatile struct CIA *ciaptr;
33 unsigned long baseirq;
34 } ciadata[2];
35
36
37
38
39
40 #define IRQ_IDX(source) (source & ~IRQ_MACHSPEC)
41 #define CIA_IRQ_IDX(source) (IRQ_IDX(datap->baseirq) \
42 +(source-IRQ_AMIGA_CIAA_TA))
43
44
45
46
47
48
49
50
51
52
53
54
55 static void
56 ami_int1(int irq, struct pt_regs *fp, void *data),
57 ami_int2(int irq, struct pt_regs *fp, void *data),
58 ami_int3(int irq, struct pt_regs *fp, void *data),
59 ami_int4(int irq, struct pt_regs *fp, void *data),
60 ami_int5(int irq, struct pt_regs *fp, void *data),
61 ami_int6(int irq, struct pt_regs *fp, void *data),
62 ami_int7(int irq, struct pt_regs *fp, void *data),
63 ami_intcia(int irq, struct pt_regs *fp, void *data);
64
65 void amiga_init_INTS (void)
66 {
67 int i;
68
69
70 for (i = 0; i < NUM_AMIGA_SOURCES; i++)
71 ami_lists[i] = NULL;
72
73 add_isr (IRQ1, ami_int1, 0, NULL, "int1 handler");
74 add_isr (IRQ2, ami_int2, 0, NULL, "int2 handler");
75 add_isr (IRQ3, ami_int3, 0, NULL, "int3 handler");
76 add_isr (IRQ4, ami_int4, 0, NULL, "int4 handler");
77 add_isr (IRQ5, ami_int5, 0, NULL, "int5 handler");
78 add_isr (IRQ6, ami_int6, 0, NULL, "int6 handler");
79 add_isr (IRQ7, ami_int7, 0, NULL, "int7 handler");
80
81
82 ciadata[0].ciaptr = &ciaa;
83 ciadata[0].baseirq = IRQ_AMIGA_CIAA_TA;
84 add_isr (IRQ_AMIGA_PORTS, ami_intcia, 0, NULL, "Amiga CIAA");
85 ciadata[1].ciaptr = &ciab;
86 ciadata[1].baseirq = IRQ_AMIGA_CIAB_TA;
87 add_isr (IRQ_AMIGA_EXTER, ami_intcia, 0, NULL, "Amiga CIAB");
88
89
90 custom.intena = 0x7fff;
91 custom.intreq = 0x7fff;
92 custom.intena = 0xc000;
93
94
95 ciaa.icr = 0x7f;
96 ciab.icr = 0x7f;
97
98
99 i = ciaa.icr;
100 i = ciab.icr;
101 }
102
103
104
105
106
107
108 static void ami_int1 (int irq, struct pt_regs *fp, void *data)
109 {
110 ushort ints = custom.intreqr & custom.intenar;
111
112
113 if (ints & IF_TBE) {
114 if (ami_lists[IRQ_IDX(IRQ_AMIGA_TBE)]) {
115 call_isr_list (IRQ_AMIGA_TBE,
116 ami_lists[IRQ_IDX(IRQ_AMIGA_TBE)], fp);
117
118
119
120
121
122
123 } else
124
125 custom.intreq = IF_TBE;
126 }
127
128
129 if (ints & IF_DSKBLK) {
130 call_isr_list (IRQ_AMIGA_DSKBLK,
131 ami_lists[IRQ_IDX(IRQ_AMIGA_DSKBLK)], fp);
132
133
134 custom.intreq = IF_DSKBLK;
135 }
136
137
138 if (ints & IF_SOFT) {
139 call_isr_list (IRQ_AMIGA_SOFT,
140 ami_lists[IRQ_IDX(IRQ_AMIGA_SOFT)], fp);
141
142
143 custom.intreq = IF_SOFT;
144 }
145 }
146
147 static void ami_int2 (int irq, struct pt_regs *fp, void *data)
148 {
149 ushort ints = custom.intreqr & custom.intenar;
150
151 if (ints & IF_PORTS) {
152
153 call_isr_list (IRQ_AMIGA_PORTS,
154 ami_lists[IRQ_IDX(IRQ_AMIGA_PORTS)], fp);
155
156
157 custom.intreq = IF_PORTS;
158 }
159 }
160
161 static void ami_int3 (int irq, struct pt_regs *fp, void *data)
162 {
163 ushort ints = custom.intreqr & custom.intenar;
164
165
166 if (ints & IF_COPER) {
167 call_isr_list (IRQ_AMIGA_COPPER,
168 ami_lists[IRQ_IDX(IRQ_AMIGA_COPPER)], fp);
169
170
171 custom.intreq = IF_COPER;
172 }
173
174
175 if (ints & IF_VERTB) {
176 call_isr_list (IRQ_AMIGA_VERTB,
177 ami_lists[IRQ_IDX(IRQ_AMIGA_VERTB)], fp);
178
179
180 custom.intreq = IF_VERTB;
181 }
182
183
184 if (ints & IF_BLIT) {
185 call_isr_list (IRQ_AMIGA_BLIT,
186 ami_lists[IRQ_IDX(IRQ_AMIGA_BLIT)], fp);
187
188
189 custom.intreq = IF_BLIT;
190 }
191 }
192
193 static void ami_int4 (int irq, struct pt_regs *fp, void *data)
194 {
195 ushort ints = custom.intreqr & custom.intenar;
196
197
198 if (ints & IF_AUD0) {
199 call_isr_list (IRQ_AMIGA_AUD0,
200 ami_lists[IRQ_IDX(IRQ_AMIGA_AUD0)], fp);
201
202
203 custom.intreq = IF_AUD0;
204 }
205
206
207 if (ints & IF_AUD1) {
208 call_isr_list (IRQ_AMIGA_AUD1,
209 ami_lists[IRQ_IDX(IRQ_AMIGA_AUD1)], fp);
210
211
212 custom.intreq = IF_AUD1;
213 }
214
215
216 if (ints & IF_AUD2) {
217 call_isr_list (IRQ_AMIGA_AUD2,
218 ami_lists[IRQ_IDX(IRQ_AMIGA_AUD2)], fp);
219
220
221 custom.intreq = IF_AUD2;
222 }
223
224
225 if (ints & IF_AUD3) {
226 call_isr_list (IRQ_AMIGA_AUD3,
227 ami_lists[IRQ_IDX(IRQ_AMIGA_AUD3)], fp);
228
229
230 custom.intreq = IF_AUD3;
231 }
232 }
233
234 static void ami_int5 (int irq, struct pt_regs *fp, void *data)
235 {
236 ushort ints = custom.intreqr & custom.intenar;
237
238
239 if (ints & IF_RBF) {
240 if (ami_lists[IRQ_IDX(IRQ_AMIGA_RBF)]) {
241 call_isr_list (IRQ_AMIGA_RBF,
242 ami_lists[IRQ_IDX(IRQ_AMIGA_RBF)], fp);
243
244 } else
245
246 custom.intreq = IF_RBF;
247 }
248
249
250 if (ints & IF_DSKSYN) {
251 call_isr_list (IRQ_AMIGA_DSKSYN,
252 ami_lists[IRQ_IDX(IRQ_AMIGA_DSKSYN)], fp);
253
254
255 custom.intreq = IF_DSKSYN;
256 }
257 }
258
259 static void ami_int6 (int irq, struct pt_regs *fp, void *data)
260 {
261 ushort ints = custom.intreqr & custom.intenar;
262
263 if (ints & IF_EXTER) {
264
265 call_isr_list (IRQ_AMIGA_EXTER,
266 ami_lists[IRQ_IDX(IRQ_AMIGA_EXTER)], fp);
267
268
269 custom.intreq = IF_EXTER;
270 }
271 }
272
273 static void ami_int7 (int irq, struct pt_regs *fp, void *data)
274 {
275 panic ("level 7 interrupt received\n");
276 }
277
278 static void ami_intcia (int irq, struct pt_regs *fp, void *data)
279 {
280
281 struct ciadata *datap;
282 u_char cia_ints;
283
284
285 if (irq == IRQ_AMIGA_PORTS)
286 datap = &ciadata[0];
287 else
288 datap = &ciadata[1];
289
290 cia_ints = datap->ciaptr->icr;
291
292
293 if (cia_ints & CIA_ICR_TA)
294 call_isr_list (IRQ_AMIGA_CIAA_TA,
295 ami_lists[CIA_IRQ_IDX(IRQ_AMIGA_CIAA_TA)], fp);
296
297
298 if (cia_ints & CIA_ICR_TB)
299 call_isr_list (IRQ_AMIGA_CIAA_TB,
300 ami_lists[CIA_IRQ_IDX(IRQ_AMIGA_CIAA_TB)], fp);
301
302
303 if (cia_ints & CIA_ICR_ALRM)
304 call_isr_list (IRQ_AMIGA_CIAA_ALRM,
305 ami_lists[CIA_IRQ_IDX(IRQ_AMIGA_CIAA_ALRM)], fp);
306
307
308 if (cia_ints & CIA_ICR_SP)
309 call_isr_list (IRQ_AMIGA_CIAA_SP,
310 ami_lists[CIA_IRQ_IDX(IRQ_AMIGA_CIAA_SP)], fp);
311
312
313 if (cia_ints & CIA_ICR_FLG)
314 call_isr_list (IRQ_AMIGA_CIAA_FLG,
315 ami_lists[CIA_IRQ_IDX(IRQ_AMIGA_CIAA_FLG)], fp);
316 }
317
318
319
320
321
322
323
324
325
326
327 int amiga_add_isr (unsigned long source, isrfunc isr, int pri, void
328 *data, char *name)
329 {
330 unsigned long amiga_source = source & ~IRQ_MACHSPEC;
331 isr_node_t *p;
332
333 if (amiga_source > NUM_AMIGA_SOURCES) {
334 printk ("amiga_add_isr: Unknown interrupt source %ld\n", source);
335 return 0;
336 }
337
338 p = new_isr_node();
339 p->isr = isr;
340 p->pri = pri;
341 p->data = data;
342 p->name = name;
343 p->next = NULL;
344 insert_isr (&ami_lists[amiga_source], p);
345
346
347 custom.intena = IF_SETCLR | ami_intena_vals[amiga_source];
348
349
350 if (source >= IRQ_AMIGA_CIAA_TA && source <= IRQ_AMIGA_CIAA_FLG)
351 ciaa.icr = 0x80 | (1 << (source - IRQ_AMIGA_CIAA_TA));
352
353
354 if (source >= IRQ_AMIGA_CIAB_TA && source <= IRQ_AMIGA_CIAB_FLG)
355 ciab.icr = 0x80 | (1 << (source - IRQ_AMIGA_CIAB_TA));
356
357 return 1;
358 }
359
360 int amiga_get_irq_list( char *buf, int len )
361 { int i;
362 isr_node_t *p;
363
364 for( i = 0; i < NUM_AMIGA_SOURCES; ++i ) {
365 if (!ami_lists[i])
366 continue;
367 len += sprintf( buf+len, "ami %2d: ???????? ", i );
368 for( p = ami_lists[i]; p; p = p->next ) {
369 len += sprintf( buf+len, "%s\n", p->name );
370 if (p->next)
371 len += sprintf( buf+len, " " );
372 }
373 }
374
375 return( len );
376 }