This source file includes following definitions.
- enable_local0_irq
- disable_local0_irq
- enable_local1_irq
- disable_local1_irq
- enable_local2_irq
- disable_local2_irq
- enable_local3_irq
- disable_local3_irq
- indy_local0_irqdispatch
- indy_local1_irqdispatch
- indy_buserror_irq
- plat_irq_dispatch
- arch_init_irq
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/types.h>
14 #include <linux/init.h>
15 #include <linux/kernel_stat.h>
16 #include <linux/interrupt.h>
17 #include <linux/ftrace.h>
18
19 #include <asm/irq_cpu.h>
20 #include <asm/sgi/hpc3.h>
21 #include <asm/sgi/ip22.h>
22
23
24 #undef USE_LIO3_IRQ
25
26 struct sgint_regs *sgint;
27
28 static char lc0msk_to_irqnr[256];
29 static char lc1msk_to_irqnr[256];
30 static char lc2msk_to_irqnr[256];
31 static char lc3msk_to_irqnr[256];
32
33 extern int ip22_eisa_init(void);
34
35 static void enable_local0_irq(struct irq_data *d)
36 {
37
38
39 if (d->irq != SGI_MAP_0_IRQ)
40 sgint->imask0 |= (1 << (d->irq - SGINT_LOCAL0));
41 }
42
43 static void disable_local0_irq(struct irq_data *d)
44 {
45 sgint->imask0 &= ~(1 << (d->irq - SGINT_LOCAL0));
46 }
47
48 static struct irq_chip ip22_local0_irq_type = {
49 .name = "IP22 local 0",
50 .irq_mask = disable_local0_irq,
51 .irq_unmask = enable_local0_irq,
52 };
53
54 static void enable_local1_irq(struct irq_data *d)
55 {
56
57
58 if (d->irq != SGI_MAP_1_IRQ)
59 sgint->imask1 |= (1 << (d->irq - SGINT_LOCAL1));
60 }
61
62 static void disable_local1_irq(struct irq_data *d)
63 {
64 sgint->imask1 &= ~(1 << (d->irq - SGINT_LOCAL1));
65 }
66
67 static struct irq_chip ip22_local1_irq_type = {
68 .name = "IP22 local 1",
69 .irq_mask = disable_local1_irq,
70 .irq_unmask = enable_local1_irq,
71 };
72
73 static void enable_local2_irq(struct irq_data *d)
74 {
75 sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
76 sgint->cmeimask0 |= (1 << (d->irq - SGINT_LOCAL2));
77 }
78
79 static void disable_local2_irq(struct irq_data *d)
80 {
81 sgint->cmeimask0 &= ~(1 << (d->irq - SGINT_LOCAL2));
82 if (!sgint->cmeimask0)
83 sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
84 }
85
86 static struct irq_chip ip22_local2_irq_type = {
87 .name = "IP22 local 2",
88 .irq_mask = disable_local2_irq,
89 .irq_unmask = enable_local2_irq,
90 };
91
92 static void enable_local3_irq(struct irq_data *d)
93 {
94 sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
95 sgint->cmeimask1 |= (1 << (d->irq - SGINT_LOCAL3));
96 }
97
98 static void disable_local3_irq(struct irq_data *d)
99 {
100 sgint->cmeimask1 &= ~(1 << (d->irq - SGINT_LOCAL3));
101 if (!sgint->cmeimask1)
102 sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
103 }
104
105 static struct irq_chip ip22_local3_irq_type = {
106 .name = "IP22 local 3",
107 .irq_mask = disable_local3_irq,
108 .irq_unmask = enable_local3_irq,
109 };
110
111 static void indy_local0_irqdispatch(void)
112 {
113 u8 mask = sgint->istat0 & sgint->imask0;
114 u8 mask2;
115 int irq;
116
117 if (mask & SGINT_ISTAT0_LIO2) {
118 mask2 = sgint->vmeistat & sgint->cmeimask0;
119 irq = lc2msk_to_irqnr[mask2];
120 } else
121 irq = lc0msk_to_irqnr[mask];
122
123
124
125
126
127 if (irq)
128 do_IRQ(irq);
129 else
130 do_IRQ(SGINT_LOCAL0 + 0);
131 }
132
133 static void indy_local1_irqdispatch(void)
134 {
135 u8 mask = sgint->istat1 & sgint->imask1;
136 u8 mask2;
137 int irq;
138
139 if (mask & SGINT_ISTAT1_LIO3) {
140 mask2 = sgint->vmeistat & sgint->cmeimask1;
141 irq = lc3msk_to_irqnr[mask2];
142 } else
143 irq = lc1msk_to_irqnr[mask];
144
145
146 if (irq)
147 do_IRQ(irq);
148 }
149
150 extern void ip22_be_interrupt(int irq);
151
152 static void __irq_entry indy_buserror_irq(void)
153 {
154 int irq = SGI_BUSERR_IRQ;
155
156 irq_enter();
157 kstat_incr_irq_this_cpu(irq);
158 ip22_be_interrupt(irq);
159 irq_exit();
160 }
161
162 static struct irqaction local0_cascade = {
163 .handler = no_action,
164 .flags = IRQF_NO_THREAD,
165 .name = "local0 cascade",
166 };
167
168 static struct irqaction local1_cascade = {
169 .handler = no_action,
170 .flags = IRQF_NO_THREAD,
171 .name = "local1 cascade",
172 };
173
174 static struct irqaction buserr = {
175 .handler = no_action,
176 .flags = IRQF_NO_THREAD,
177 .name = "Bus Error",
178 };
179
180 static struct irqaction map0_cascade = {
181 .handler = no_action,
182 .flags = IRQF_NO_THREAD,
183 .name = "mapable0 cascade",
184 };
185
186 #ifdef USE_LIO3_IRQ
187 static struct irqaction map1_cascade = {
188 .handler = no_action,
189 .flags = IRQF_NO_THREAD,
190 .name = "mapable1 cascade",
191 };
192 #define SGI_INTERRUPTS SGINT_END
193 #else
194 #define SGI_INTERRUPTS SGINT_LOCAL3
195 #endif
196
197 extern void indy_8254timer_irq(void);
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 asmlinkage void plat_irq_dispatch(void)
228 {
229 unsigned int pending = read_c0_status() & read_c0_cause();
230
231
232
233
234 if (pending & CAUSEF_IP7)
235 do_IRQ(SGI_TIMER_IRQ);
236 else if (pending & CAUSEF_IP2)
237 indy_local0_irqdispatch();
238 else if (pending & CAUSEF_IP3)
239 indy_local1_irqdispatch();
240 else if (pending & CAUSEF_IP6)
241 indy_buserror_irq();
242 else if (pending & (CAUSEF_IP4 | CAUSEF_IP5))
243 indy_8254timer_irq();
244 }
245
246 void __init arch_init_irq(void)
247 {
248 int i;
249
250
251 for (i = 0; i < 256; i++) {
252 if (i & 0x80) {
253 lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 7;
254 lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 7;
255 lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 7;
256 lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 7;
257 } else if (i & 0x40) {
258 lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 6;
259 lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 6;
260 lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 6;
261 lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 6;
262 } else if (i & 0x20) {
263 lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 5;
264 lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 5;
265 lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 5;
266 lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 5;
267 } else if (i & 0x10) {
268 lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 4;
269 lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 4;
270 lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 4;
271 lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 4;
272 } else if (i & 0x08) {
273 lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 3;
274 lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 3;
275 lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 3;
276 lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 3;
277 } else if (i & 0x04) {
278 lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 2;
279 lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 2;
280 lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 2;
281 lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 2;
282 } else if (i & 0x02) {
283 lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 1;
284 lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 1;
285 lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 1;
286 lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 1;
287 } else if (i & 0x01) {
288 lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 0;
289 lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 0;
290 lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 0;
291 lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 0;
292 } else {
293 lc0msk_to_irqnr[i] = 0;
294 lc1msk_to_irqnr[i] = 0;
295 lc2msk_to_irqnr[i] = 0;
296 lc3msk_to_irqnr[i] = 0;
297 }
298 }
299
300
301 sgint->imask0 = 0;
302 sgint->imask1 = 0;
303 sgint->cmeimask0 = 0;
304 sgint->cmeimask1 = 0;
305
306
307 mips_cpu_irq_init();
308
309 for (i = SGINT_LOCAL0; i < SGI_INTERRUPTS; i++) {
310 struct irq_chip *handler;
311
312 if (i < SGINT_LOCAL1)
313 handler = &ip22_local0_irq_type;
314 else if (i < SGINT_LOCAL2)
315 handler = &ip22_local1_irq_type;
316 else if (i < SGINT_LOCAL3)
317 handler = &ip22_local2_irq_type;
318 else
319 handler = &ip22_local3_irq_type;
320
321 irq_set_chip_and_handler(i, handler, handle_level_irq);
322 }
323
324
325 setup_irq(SGI_LOCAL_0_IRQ, &local0_cascade);
326 setup_irq(SGI_LOCAL_1_IRQ, &local1_cascade);
327 setup_irq(SGI_BUSERR_IRQ, &buserr);
328
329
330 setup_irq(SGI_MAP_0_IRQ, &map0_cascade);
331 #ifdef USE_LIO3_IRQ
332 setup_irq(SGI_MAP_1_IRQ, &map1_cascade);
333 #endif
334
335 #ifdef CONFIG_EISA
336 if (ip22_is_fullhouse())
337 ip22_eisa_init();
338 #endif
339 }