]>
Commit | Line | Data |
---|---|---|
bf4152dd | 1 | /* |
58862699 | 2 | * arch/ppc/syslib/ipic.c |
bf4152dd KP |
3 | * |
4 | * IPIC routines implementations. | |
5 | * | |
6 | * Copyright 2005 Freescale Semiconductor, Inc. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU General Public License as published by the | |
10 | * Free Software Foundation; either version 2 of the License, or (at your | |
11 | * option) any later version. | |
12 | */ | |
13 | #include <linux/kernel.h> | |
14 | #include <linux/init.h> | |
15 | #include <linux/errno.h> | |
16 | #include <linux/reboot.h> | |
17 | #include <linux/slab.h> | |
18 | #include <linux/stddef.h> | |
19 | #include <linux/sched.h> | |
20 | #include <linux/signal.h> | |
21 | #include <linux/sysdev.h> | |
22 | #include <asm/irq.h> | |
23 | #include <asm/io.h> | |
24 | #include <asm/ipic.h> | |
25 | #include <asm/mpc83xx.h> | |
26 | ||
27 | #include "ipic.h" | |
28 | ||
29 | static struct ipic p_ipic; | |
30 | static struct ipic * primary_ipic; | |
31 | ||
32 | static struct ipic_info ipic_info[] = { | |
33 | [9] = { | |
34 | .pend = IPIC_SIPNR_H, | |
35 | .mask = IPIC_SIMSR_H, | |
36 | .prio = IPIC_SIPRR_D, | |
37 | .force = IPIC_SIFCR_H, | |
38 | .bit = 24, | |
39 | .prio_mask = 0, | |
40 | }, | |
41 | [10] = { | |
42 | .pend = IPIC_SIPNR_H, | |
43 | .mask = IPIC_SIMSR_H, | |
44 | .prio = IPIC_SIPRR_D, | |
45 | .force = IPIC_SIFCR_H, | |
46 | .bit = 25, | |
47 | .prio_mask = 1, | |
48 | }, | |
49 | [11] = { | |
50 | .pend = IPIC_SIPNR_H, | |
51 | .mask = IPIC_SIMSR_H, | |
52 | .prio = IPIC_SIPRR_D, | |
53 | .force = IPIC_SIFCR_H, | |
54 | .bit = 26, | |
55 | .prio_mask = 2, | |
56 | }, | |
57 | [14] = { | |
58 | .pend = IPIC_SIPNR_H, | |
59 | .mask = IPIC_SIMSR_H, | |
60 | .prio = IPIC_SIPRR_D, | |
61 | .force = IPIC_SIFCR_H, | |
62 | .bit = 29, | |
63 | .prio_mask = 5, | |
64 | }, | |
65 | [15] = { | |
66 | .pend = IPIC_SIPNR_H, | |
67 | .mask = IPIC_SIMSR_H, | |
68 | .prio = IPIC_SIPRR_D, | |
69 | .force = IPIC_SIFCR_H, | |
70 | .bit = 30, | |
71 | .prio_mask = 6, | |
72 | }, | |
73 | [16] = { | |
74 | .pend = IPIC_SIPNR_H, | |
75 | .mask = IPIC_SIMSR_H, | |
76 | .prio = IPIC_SIPRR_D, | |
77 | .force = IPIC_SIFCR_H, | |
78 | .bit = 31, | |
79 | .prio_mask = 7, | |
80 | }, | |
81 | [17] = { | |
82 | .pend = IPIC_SEPNR, | |
83 | .mask = IPIC_SEMSR, | |
84 | .prio = IPIC_SMPRR_A, | |
85 | .force = IPIC_SEFCR, | |
86 | .bit = 1, | |
87 | .prio_mask = 5, | |
88 | }, | |
89 | [18] = { | |
90 | .pend = IPIC_SEPNR, | |
91 | .mask = IPIC_SEMSR, | |
92 | .prio = IPIC_SMPRR_A, | |
93 | .force = IPIC_SEFCR, | |
94 | .bit = 2, | |
95 | .prio_mask = 6, | |
96 | }, | |
97 | [19] = { | |
98 | .pend = IPIC_SEPNR, | |
99 | .mask = IPIC_SEMSR, | |
100 | .prio = IPIC_SMPRR_A, | |
101 | .force = IPIC_SEFCR, | |
102 | .bit = 3, | |
103 | .prio_mask = 7, | |
104 | }, | |
105 | [20] = { | |
106 | .pend = IPIC_SEPNR, | |
107 | .mask = IPIC_SEMSR, | |
108 | .prio = IPIC_SMPRR_B, | |
109 | .force = IPIC_SEFCR, | |
110 | .bit = 4, | |
111 | .prio_mask = 4, | |
112 | }, | |
113 | [21] = { | |
114 | .pend = IPIC_SEPNR, | |
115 | .mask = IPIC_SEMSR, | |
116 | .prio = IPIC_SMPRR_B, | |
117 | .force = IPIC_SEFCR, | |
118 | .bit = 5, | |
119 | .prio_mask = 5, | |
120 | }, | |
121 | [22] = { | |
122 | .pend = IPIC_SEPNR, | |
123 | .mask = IPIC_SEMSR, | |
124 | .prio = IPIC_SMPRR_B, | |
125 | .force = IPIC_SEFCR, | |
126 | .bit = 6, | |
127 | .prio_mask = 6, | |
128 | }, | |
129 | [23] = { | |
130 | .pend = IPIC_SEPNR, | |
131 | .mask = IPIC_SEMSR, | |
132 | .prio = IPIC_SMPRR_B, | |
133 | .force = IPIC_SEFCR, | |
134 | .bit = 7, | |
135 | .prio_mask = 7, | |
136 | }, | |
137 | [32] = { | |
138 | .pend = IPIC_SIPNR_H, | |
139 | .mask = IPIC_SIMSR_H, | |
140 | .prio = IPIC_SIPRR_A, | |
141 | .force = IPIC_SIFCR_H, | |
142 | .bit = 0, | |
143 | .prio_mask = 0, | |
144 | }, | |
145 | [33] = { | |
146 | .pend = IPIC_SIPNR_H, | |
147 | .mask = IPIC_SIMSR_H, | |
148 | .prio = IPIC_SIPRR_A, | |
149 | .force = IPIC_SIFCR_H, | |
150 | .bit = 1, | |
151 | .prio_mask = 1, | |
152 | }, | |
153 | [34] = { | |
154 | .pend = IPIC_SIPNR_H, | |
155 | .mask = IPIC_SIMSR_H, | |
156 | .prio = IPIC_SIPRR_A, | |
157 | .force = IPIC_SIFCR_H, | |
158 | .bit = 2, | |
159 | .prio_mask = 2, | |
160 | }, | |
161 | [35] = { | |
162 | .pend = IPIC_SIPNR_H, | |
163 | .mask = IPIC_SIMSR_H, | |
164 | .prio = IPIC_SIPRR_A, | |
165 | .force = IPIC_SIFCR_H, | |
166 | .bit = 3, | |
167 | .prio_mask = 3, | |
168 | }, | |
169 | [36] = { | |
170 | .pend = IPIC_SIPNR_H, | |
171 | .mask = IPIC_SIMSR_H, | |
172 | .prio = IPIC_SIPRR_A, | |
173 | .force = IPIC_SIFCR_H, | |
174 | .bit = 4, | |
175 | .prio_mask = 4, | |
176 | }, | |
177 | [37] = { | |
178 | .pend = IPIC_SIPNR_H, | |
179 | .mask = IPIC_SIMSR_H, | |
180 | .prio = IPIC_SIPRR_A, | |
181 | .force = IPIC_SIFCR_H, | |
182 | .bit = 5, | |
183 | .prio_mask = 5, | |
184 | }, | |
185 | [38] = { | |
186 | .pend = IPIC_SIPNR_H, | |
187 | .mask = IPIC_SIMSR_H, | |
188 | .prio = IPIC_SIPRR_A, | |
189 | .force = IPIC_SIFCR_H, | |
190 | .bit = 6, | |
191 | .prio_mask = 6, | |
192 | }, | |
193 | [39] = { | |
194 | .pend = IPIC_SIPNR_H, | |
195 | .mask = IPIC_SIMSR_H, | |
196 | .prio = IPIC_SIPRR_A, | |
197 | .force = IPIC_SIFCR_H, | |
198 | .bit = 7, | |
199 | .prio_mask = 7, | |
200 | }, | |
201 | [48] = { | |
202 | .pend = IPIC_SEPNR, | |
203 | .mask = IPIC_SEMSR, | |
204 | .prio = IPIC_SMPRR_A, | |
205 | .force = IPIC_SEFCR, | |
206 | .bit = 0, | |
207 | .prio_mask = 4, | |
208 | }, | |
209 | [64] = { | |
210 | .pend = IPIC_SIPNR_H, | |
211 | .mask = IPIC_SIMSR_L, | |
212 | .prio = IPIC_SMPRR_A, | |
213 | .force = IPIC_SIFCR_L, | |
214 | .bit = 0, | |
215 | .prio_mask = 0, | |
216 | }, | |
217 | [65] = { | |
218 | .pend = IPIC_SIPNR_H, | |
219 | .mask = IPIC_SIMSR_L, | |
220 | .prio = IPIC_SMPRR_A, | |
221 | .force = IPIC_SIFCR_L, | |
222 | .bit = 1, | |
223 | .prio_mask = 1, | |
224 | }, | |
225 | [66] = { | |
226 | .pend = IPIC_SIPNR_H, | |
227 | .mask = IPIC_SIMSR_L, | |
228 | .prio = IPIC_SMPRR_A, | |
229 | .force = IPIC_SIFCR_L, | |
230 | .bit = 2, | |
231 | .prio_mask = 2, | |
232 | }, | |
233 | [67] = { | |
234 | .pend = IPIC_SIPNR_H, | |
235 | .mask = IPIC_SIMSR_L, | |
236 | .prio = IPIC_SMPRR_A, | |
237 | .force = IPIC_SIFCR_L, | |
238 | .bit = 3, | |
239 | .prio_mask = 3, | |
240 | }, | |
241 | [68] = { | |
242 | .pend = IPIC_SIPNR_H, | |
243 | .mask = IPIC_SIMSR_L, | |
244 | .prio = IPIC_SMPRR_B, | |
245 | .force = IPIC_SIFCR_L, | |
246 | .bit = 4, | |
247 | .prio_mask = 0, | |
248 | }, | |
249 | [69] = { | |
250 | .pend = IPIC_SIPNR_H, | |
251 | .mask = IPIC_SIMSR_L, | |
252 | .prio = IPIC_SMPRR_B, | |
253 | .force = IPIC_SIFCR_L, | |
254 | .bit = 5, | |
255 | .prio_mask = 1, | |
256 | }, | |
257 | [70] = { | |
258 | .pend = IPIC_SIPNR_H, | |
259 | .mask = IPIC_SIMSR_L, | |
260 | .prio = IPIC_SMPRR_B, | |
261 | .force = IPIC_SIFCR_L, | |
262 | .bit = 6, | |
263 | .prio_mask = 2, | |
264 | }, | |
265 | [71] = { | |
266 | .pend = IPIC_SIPNR_H, | |
267 | .mask = IPIC_SIMSR_L, | |
268 | .prio = IPIC_SMPRR_B, | |
269 | .force = IPIC_SIFCR_L, | |
270 | .bit = 7, | |
271 | .prio_mask = 3, | |
272 | }, | |
273 | [72] = { | |
274 | .pend = IPIC_SIPNR_H, | |
275 | .mask = IPIC_SIMSR_L, | |
276 | .prio = 0, | |
277 | .force = IPIC_SIFCR_L, | |
278 | .bit = 8, | |
279 | }, | |
280 | [73] = { | |
281 | .pend = IPIC_SIPNR_H, | |
282 | .mask = IPIC_SIMSR_L, | |
283 | .prio = 0, | |
284 | .force = IPIC_SIFCR_L, | |
285 | .bit = 9, | |
286 | }, | |
287 | [74] = { | |
288 | .pend = IPIC_SIPNR_H, | |
289 | .mask = IPIC_SIMSR_L, | |
290 | .prio = 0, | |
291 | .force = IPIC_SIFCR_L, | |
292 | .bit = 10, | |
293 | }, | |
294 | [75] = { | |
295 | .pend = IPIC_SIPNR_H, | |
296 | .mask = IPIC_SIMSR_L, | |
297 | .prio = 0, | |
298 | .force = IPIC_SIFCR_L, | |
299 | .bit = 11, | |
300 | }, | |
301 | [76] = { | |
302 | .pend = IPIC_SIPNR_H, | |
303 | .mask = IPIC_SIMSR_L, | |
304 | .prio = 0, | |
305 | .force = IPIC_SIFCR_L, | |
306 | .bit = 12, | |
307 | }, | |
308 | [77] = { | |
309 | .pend = IPIC_SIPNR_H, | |
310 | .mask = IPIC_SIMSR_L, | |
311 | .prio = 0, | |
312 | .force = IPIC_SIFCR_L, | |
313 | .bit = 13, | |
314 | }, | |
315 | [78] = { | |
316 | .pend = IPIC_SIPNR_H, | |
317 | .mask = IPIC_SIMSR_L, | |
318 | .prio = 0, | |
319 | .force = IPIC_SIFCR_L, | |
320 | .bit = 14, | |
321 | }, | |
322 | [79] = { | |
323 | .pend = IPIC_SIPNR_H, | |
324 | .mask = IPIC_SIMSR_L, | |
325 | .prio = 0, | |
326 | .force = IPIC_SIFCR_L, | |
327 | .bit = 15, | |
328 | }, | |
329 | [80] = { | |
330 | .pend = IPIC_SIPNR_H, | |
331 | .mask = IPIC_SIMSR_L, | |
332 | .prio = 0, | |
333 | .force = IPIC_SIFCR_L, | |
334 | .bit = 16, | |
335 | }, | |
336 | [84] = { | |
337 | .pend = IPIC_SIPNR_H, | |
338 | .mask = IPIC_SIMSR_L, | |
339 | .prio = 0, | |
340 | .force = IPIC_SIFCR_L, | |
341 | .bit = 20, | |
342 | }, | |
343 | [85] = { | |
344 | .pend = IPIC_SIPNR_H, | |
345 | .mask = IPIC_SIMSR_L, | |
346 | .prio = 0, | |
347 | .force = IPIC_SIFCR_L, | |
348 | .bit = 21, | |
349 | }, | |
350 | [90] = { | |
351 | .pend = IPIC_SIPNR_H, | |
352 | .mask = IPIC_SIMSR_L, | |
353 | .prio = 0, | |
354 | .force = IPIC_SIFCR_L, | |
355 | .bit = 26, | |
356 | }, | |
357 | [91] = { | |
358 | .pend = IPIC_SIPNR_H, | |
359 | .mask = IPIC_SIMSR_L, | |
360 | .prio = 0, | |
361 | .force = IPIC_SIFCR_L, | |
362 | .bit = 27, | |
363 | }, | |
364 | }; | |
365 | ||
366 | static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg) | |
367 | { | |
368 | return in_be32(base + (reg >> 2)); | |
369 | } | |
370 | ||
371 | static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 value) | |
372 | { | |
373 | out_be32(base + (reg >> 2), value); | |
374 | } | |
375 | ||
376 | static inline struct ipic * ipic_from_irq(unsigned int irq) | |
377 | { | |
378 | return primary_ipic; | |
379 | } | |
380 | ||
381 | static void ipic_enable_irq(unsigned int irq) | |
382 | { | |
383 | struct ipic *ipic = ipic_from_irq(irq); | |
384 | unsigned int src = irq - ipic->irq_offset; | |
385 | u32 temp; | |
386 | ||
387 | temp = ipic_read(ipic->regs, ipic_info[src].mask); | |
388 | temp |= (1 << (31 - ipic_info[src].bit)); | |
389 | ipic_write(ipic->regs, ipic_info[src].mask, temp); | |
390 | } | |
391 | ||
392 | static void ipic_disable_irq(unsigned int irq) | |
393 | { | |
394 | struct ipic *ipic = ipic_from_irq(irq); | |
395 | unsigned int src = irq - ipic->irq_offset; | |
396 | u32 temp; | |
397 | ||
398 | temp = ipic_read(ipic->regs, ipic_info[src].mask); | |
399 | temp &= ~(1 << (31 - ipic_info[src].bit)); | |
400 | ipic_write(ipic->regs, ipic_info[src].mask, temp); | |
401 | } | |
402 | ||
403 | static void ipic_disable_irq_and_ack(unsigned int irq) | |
404 | { | |
405 | struct ipic *ipic = ipic_from_irq(irq); | |
406 | unsigned int src = irq - ipic->irq_offset; | |
407 | u32 temp; | |
408 | ||
409 | ipic_disable_irq(irq); | |
410 | ||
411 | temp = ipic_read(ipic->regs, ipic_info[src].pend); | |
412 | temp |= (1 << (31 - ipic_info[src].bit)); | |
413 | ipic_write(ipic->regs, ipic_info[src].pend, temp); | |
414 | } | |
415 | ||
416 | static void ipic_end_irq(unsigned int irq) | |
417 | { | |
418 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | |
419 | ipic_enable_irq(irq); | |
420 | } | |
421 | ||
422 | struct hw_interrupt_type ipic = { | |
423 | .typename = " IPIC ", | |
424 | .enable = ipic_enable_irq, | |
425 | .disable = ipic_disable_irq, | |
426 | .ack = ipic_disable_irq_and_ack, | |
427 | .end = ipic_end_irq, | |
428 | }; | |
429 | ||
430 | void __init ipic_init(phys_addr_t phys_addr, | |
431 | unsigned int flags, | |
432 | unsigned int irq_offset, | |
433 | unsigned char *senses, | |
434 | unsigned int senses_count) | |
435 | { | |
436 | u32 i, temp = 0; | |
437 | ||
438 | primary_ipic = &p_ipic; | |
439 | primary_ipic->regs = ioremap(phys_addr, MPC83xx_IPIC_SIZE); | |
440 | ||
441 | primary_ipic->irq_offset = irq_offset; | |
442 | ||
443 | ipic_write(primary_ipic->regs, IPIC_SICNR, 0x0); | |
444 | ||
445 | /* default priority scheme is grouped. If spread mode is required | |
446 | * configure SICFR accordingly */ | |
447 | if (flags & IPIC_SPREADMODE_GRP_A) | |
448 | temp |= SICFR_IPSA; | |
449 | if (flags & IPIC_SPREADMODE_GRP_D) | |
450 | temp |= SICFR_IPSD; | |
451 | if (flags & IPIC_SPREADMODE_MIX_A) | |
452 | temp |= SICFR_MPSA; | |
453 | if (flags & IPIC_SPREADMODE_MIX_B) | |
454 | temp |= SICFR_MPSB; | |
455 | ||
456 | ipic_write(primary_ipic->regs, IPIC_SICNR, temp); | |
457 | ||
458 | /* handle MCP route */ | |
459 | temp = 0; | |
460 | if (flags & IPIC_DISABLE_MCP_OUT) | |
461 | temp = SERCR_MCPR; | |
462 | ipic_write(primary_ipic->regs, IPIC_SERCR, temp); | |
463 | ||
464 | /* handle routing of IRQ0 to MCP */ | |
465 | temp = ipic_read(primary_ipic->regs, IPIC_SEMSR); | |
466 | ||
467 | if (flags & IPIC_IRQ0_MCP) | |
468 | temp |= SEMSR_SIRQ0; | |
469 | else | |
470 | temp &= ~SEMSR_SIRQ0; | |
471 | ||
472 | ipic_write(primary_ipic->regs, IPIC_SEMSR, temp); | |
473 | ||
474 | for (i = 0 ; i < NR_IPIC_INTS ; i++) { | |
475 | irq_desc[i+irq_offset].chip = &ipic; | |
476 | irq_desc[i+irq_offset].status = IRQ_LEVEL; | |
477 | } | |
478 | ||
479 | temp = 0; | |
480 | for (i = 0 ; i < senses_count ; i++) { | |
481 | if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) { | |
482 | temp |= 1 << (15 - i); | |
483 | if (i != 0) | |
484 | irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0; | |
485 | else | |
486 | irq_desc[irq_offset + MPC83xx_IRQ_EXT0].status = 0; | |
487 | } | |
488 | } | |
489 | ipic_write(primary_ipic->regs, IPIC_SECNR, temp); | |
490 | ||
491 | printk ("IPIC (%d IRQ sources, %d External IRQs) at %p\n", NR_IPIC_INTS, | |
492 | senses_count, primary_ipic->regs); | |
493 | } | |
494 | ||
495 | int ipic_set_priority(unsigned int irq, unsigned int priority) | |
496 | { | |
497 | struct ipic *ipic = ipic_from_irq(irq); | |
498 | unsigned int src = irq - ipic->irq_offset; | |
499 | u32 temp; | |
500 | ||
501 | if (priority > 7) | |
502 | return -EINVAL; | |
503 | if (src > 127) | |
504 | return -EINVAL; | |
505 | if (ipic_info[src].prio == 0) | |
506 | return -EINVAL; | |
507 | ||
508 | temp = ipic_read(ipic->regs, ipic_info[src].prio); | |
509 | ||
510 | if (priority < 4) { | |
511 | temp &= ~(0x7 << (20 + (3 - priority) * 3)); | |
512 | temp |= ipic_info[src].prio_mask << (20 + (3 - priority) * 3); | |
513 | } else { | |
514 | temp &= ~(0x7 << (4 + (7 - priority) * 3)); | |
515 | temp |= ipic_info[src].prio_mask << (4 + (7 - priority) * 3); | |
516 | } | |
517 | ||
518 | ipic_write(ipic->regs, ipic_info[src].prio, temp); | |
519 | ||
520 | return 0; | |
521 | } | |
522 | ||
523 | void ipic_set_highest_priority(unsigned int irq) | |
524 | { | |
525 | struct ipic *ipic = ipic_from_irq(irq); | |
526 | unsigned int src = irq - ipic->irq_offset; | |
527 | u32 temp; | |
528 | ||
529 | temp = ipic_read(ipic->regs, IPIC_SICFR); | |
530 | ||
531 | /* clear and set HPI */ | |
532 | temp &= 0x7f000000; | |
533 | temp |= (src & 0x7f) << 24; | |
534 | ||
535 | ipic_write(ipic->regs, IPIC_SICFR, temp); | |
536 | } | |
537 | ||
538 | void ipic_set_default_priority(void) | |
539 | { | |
540 | ipic_set_priority(MPC83xx_IRQ_TSEC1_TX, 0); | |
541 | ipic_set_priority(MPC83xx_IRQ_TSEC1_RX, 1); | |
542 | ipic_set_priority(MPC83xx_IRQ_TSEC1_ERROR, 2); | |
543 | ipic_set_priority(MPC83xx_IRQ_TSEC2_TX, 3); | |
544 | ipic_set_priority(MPC83xx_IRQ_TSEC2_RX, 4); | |
545 | ipic_set_priority(MPC83xx_IRQ_TSEC2_ERROR, 5); | |
546 | ipic_set_priority(MPC83xx_IRQ_USB2_DR, 6); | |
547 | ipic_set_priority(MPC83xx_IRQ_USB2_MPH, 7); | |
548 | ||
549 | ipic_set_priority(MPC83xx_IRQ_UART1, 0); | |
550 | ipic_set_priority(MPC83xx_IRQ_UART2, 1); | |
551 | ipic_set_priority(MPC83xx_IRQ_SEC2, 2); | |
552 | ipic_set_priority(MPC83xx_IRQ_IIC1, 5); | |
553 | ipic_set_priority(MPC83xx_IRQ_IIC2, 6); | |
554 | ipic_set_priority(MPC83xx_IRQ_SPI, 7); | |
555 | ipic_set_priority(MPC83xx_IRQ_RTC_SEC, 0); | |
556 | ipic_set_priority(MPC83xx_IRQ_PIT, 1); | |
557 | ipic_set_priority(MPC83xx_IRQ_PCI1, 2); | |
558 | ipic_set_priority(MPC83xx_IRQ_PCI2, 3); | |
559 | ipic_set_priority(MPC83xx_IRQ_EXT0, 4); | |
560 | ipic_set_priority(MPC83xx_IRQ_EXT1, 5); | |
561 | ipic_set_priority(MPC83xx_IRQ_EXT2, 6); | |
562 | ipic_set_priority(MPC83xx_IRQ_EXT3, 7); | |
563 | ipic_set_priority(MPC83xx_IRQ_RTC_ALR, 0); | |
564 | ipic_set_priority(MPC83xx_IRQ_MU, 1); | |
565 | ipic_set_priority(MPC83xx_IRQ_SBA, 2); | |
566 | ipic_set_priority(MPC83xx_IRQ_DMA, 3); | |
567 | ipic_set_priority(MPC83xx_IRQ_EXT4, 4); | |
568 | ipic_set_priority(MPC83xx_IRQ_EXT5, 5); | |
569 | ipic_set_priority(MPC83xx_IRQ_EXT6, 6); | |
570 | ipic_set_priority(MPC83xx_IRQ_EXT7, 7); | |
571 | } | |
572 | ||
573 | void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) | |
574 | { | |
575 | struct ipic *ipic = primary_ipic; | |
576 | u32 temp; | |
577 | ||
578 | temp = ipic_read(ipic->regs, IPIC_SERMR); | |
579 | temp |= (1 << (31 - mcp_irq)); | |
580 | ipic_write(ipic->regs, IPIC_SERMR, temp); | |
581 | } | |
582 | ||
583 | void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq) | |
584 | { | |
585 | struct ipic *ipic = primary_ipic; | |
586 | u32 temp; | |
587 | ||
588 | temp = ipic_read(ipic->regs, IPIC_SERMR); | |
589 | temp &= (1 << (31 - mcp_irq)); | |
590 | ipic_write(ipic->regs, IPIC_SERMR, temp); | |
591 | } | |
592 | ||
593 | u32 ipic_get_mcp_status(void) | |
594 | { | |
595 | return ipic_read(primary_ipic->regs, IPIC_SERMR); | |
596 | } | |
597 | ||
598 | void ipic_clear_mcp_status(u32 mask) | |
599 | { | |
600 | ipic_write(primary_ipic->regs, IPIC_SERMR, mask); | |
601 | } | |
602 | ||
603 | /* Return an interrupt vector or -1 if no interrupt is pending. */ | |
39e3eb72 | 604 | int ipic_get_irq(void) |
bf4152dd KP |
605 | { |
606 | int irq; | |
607 | ||
608 | irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & 0x7f; | |
609 | ||
610 | if (irq == 0) /* 0 --> no irq is pending */ | |
611 | irq = -1; | |
612 | ||
613 | return irq; | |
614 | } | |
615 | ||
616 | static struct sysdev_class ipic_sysclass = { | |
617 | set_kset_name("ipic"), | |
618 | }; | |
619 | ||
620 | static struct sys_device device_ipic = { | |
621 | .id = 0, | |
622 | .cls = &ipic_sysclass, | |
623 | }; | |
624 | ||
625 | static int __init init_ipic_sysfs(void) | |
626 | { | |
627 | int rc; | |
628 | ||
629 | if (!primary_ipic->regs) | |
630 | return -ENODEV; | |
631 | printk(KERN_DEBUG "Registering ipic with sysfs...\n"); | |
632 | ||
633 | rc = sysdev_class_register(&ipic_sysclass); | |
634 | if (rc) { | |
635 | printk(KERN_ERR "Failed registering ipic sys class\n"); | |
636 | return -ENODEV; | |
637 | } | |
638 | rc = sysdev_register(&device_ipic); | |
639 | if (rc) { | |
640 | printk(KERN_ERR "Failed registering ipic sys device\n"); | |
641 | return -ENODEV; | |
642 | } | |
643 | return 0; | |
644 | } | |
645 | ||
646 | subsys_initcall(init_ipic_sysfs); |