xref: /openbmc/linux/arch/powerpc/sysdev/ipic.c (revision 643d1f7f)
1 /*
2  * arch/powerpc/sysdev/ipic.c
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 <linux/device.h>
23 #include <linux/bootmem.h>
24 #include <linux/spinlock.h>
25 #include <asm/irq.h>
26 #include <asm/io.h>
27 #include <asm/prom.h>
28 #include <asm/ipic.h>
29 
30 #include "ipic.h"
31 
32 static struct ipic * primary_ipic;
33 static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip;
34 static DEFINE_SPINLOCK(ipic_lock);
35 
36 static struct ipic_info ipic_info[] = {
37 	[1] = {
38 		.mask	= IPIC_SIMSR_H,
39 		.prio	= IPIC_SIPRR_C,
40 		.force	= IPIC_SIFCR_H,
41 		.bit	= 16,
42 		.prio_mask = 0,
43 	},
44 	[2] = {
45 		.mask	= IPIC_SIMSR_H,
46 		.prio	= IPIC_SIPRR_C,
47 		.force	= IPIC_SIFCR_H,
48 		.bit	= 17,
49 		.prio_mask = 1,
50 	},
51 	[3] = {
52 		.mask	= IPIC_SIMSR_H,
53 		.prio	= IPIC_SIPRR_C,
54 		.force	= IPIC_SIFCR_H,
55 		.bit	= 18,
56 		.prio_mask = 2,
57 	},
58 	[4] = {
59 		.mask	= IPIC_SIMSR_H,
60 		.prio	= IPIC_SIPRR_C,
61 		.force	= IPIC_SIFCR_H,
62 		.bit	= 19,
63 		.prio_mask = 3,
64 	},
65 	[5] = {
66 		.mask	= IPIC_SIMSR_H,
67 		.prio	= IPIC_SIPRR_C,
68 		.force	= IPIC_SIFCR_H,
69 		.bit	= 20,
70 		.prio_mask = 4,
71 	},
72 	[6] = {
73 		.mask	= IPIC_SIMSR_H,
74 		.prio	= IPIC_SIPRR_C,
75 		.force	= IPIC_SIFCR_H,
76 		.bit	= 21,
77 		.prio_mask = 5,
78 	},
79 	[7] = {
80 		.mask	= IPIC_SIMSR_H,
81 		.prio	= IPIC_SIPRR_C,
82 		.force	= IPIC_SIFCR_H,
83 		.bit	= 22,
84 		.prio_mask = 6,
85 	},
86 	[8] = {
87 		.mask	= IPIC_SIMSR_H,
88 		.prio	= IPIC_SIPRR_C,
89 		.force	= IPIC_SIFCR_H,
90 		.bit	= 23,
91 		.prio_mask = 7,
92 	},
93 	[9] = {
94 		.mask	= IPIC_SIMSR_H,
95 		.prio	= IPIC_SIPRR_D,
96 		.force	= IPIC_SIFCR_H,
97 		.bit	= 24,
98 		.prio_mask = 0,
99 	},
100 	[10] = {
101 		.mask	= IPIC_SIMSR_H,
102 		.prio	= IPIC_SIPRR_D,
103 		.force	= IPIC_SIFCR_H,
104 		.bit	= 25,
105 		.prio_mask = 1,
106 	},
107 	[11] = {
108 		.mask	= IPIC_SIMSR_H,
109 		.prio	= IPIC_SIPRR_D,
110 		.force	= IPIC_SIFCR_H,
111 		.bit	= 26,
112 		.prio_mask = 2,
113 	},
114 	[12] = {
115 		.mask	= IPIC_SIMSR_H,
116 		.prio	= IPIC_SIPRR_D,
117 		.force	= IPIC_SIFCR_H,
118 		.bit	= 27,
119 		.prio_mask = 3,
120 	},
121 	[13] = {
122 		.mask	= IPIC_SIMSR_H,
123 		.prio	= IPIC_SIPRR_D,
124 		.force	= IPIC_SIFCR_H,
125 		.bit	= 28,
126 		.prio_mask = 4,
127 	},
128 	[14] = {
129 		.mask	= IPIC_SIMSR_H,
130 		.prio	= IPIC_SIPRR_D,
131 		.force	= IPIC_SIFCR_H,
132 		.bit	= 29,
133 		.prio_mask = 5,
134 	},
135 	[15] = {
136 		.mask	= IPIC_SIMSR_H,
137 		.prio	= IPIC_SIPRR_D,
138 		.force	= IPIC_SIFCR_H,
139 		.bit	= 30,
140 		.prio_mask = 6,
141 	},
142 	[16] = {
143 		.mask	= IPIC_SIMSR_H,
144 		.prio	= IPIC_SIPRR_D,
145 		.force	= IPIC_SIFCR_H,
146 		.bit	= 31,
147 		.prio_mask = 7,
148 	},
149 	[17] = {
150 		.ack	= IPIC_SEPNR,
151 		.mask	= IPIC_SEMSR,
152 		.prio	= IPIC_SMPRR_A,
153 		.force	= IPIC_SEFCR,
154 		.bit	= 1,
155 		.prio_mask = 5,
156 	},
157 	[18] = {
158 		.ack	= IPIC_SEPNR,
159 		.mask	= IPIC_SEMSR,
160 		.prio	= IPIC_SMPRR_A,
161 		.force	= IPIC_SEFCR,
162 		.bit	= 2,
163 		.prio_mask = 6,
164 	},
165 	[19] = {
166 		.ack	= IPIC_SEPNR,
167 		.mask	= IPIC_SEMSR,
168 		.prio	= IPIC_SMPRR_A,
169 		.force	= IPIC_SEFCR,
170 		.bit	= 3,
171 		.prio_mask = 7,
172 	},
173 	[20] = {
174 		.ack	= IPIC_SEPNR,
175 		.mask	= IPIC_SEMSR,
176 		.prio	= IPIC_SMPRR_B,
177 		.force	= IPIC_SEFCR,
178 		.bit	= 4,
179 		.prio_mask = 4,
180 	},
181 	[21] = {
182 		.ack	= IPIC_SEPNR,
183 		.mask	= IPIC_SEMSR,
184 		.prio	= IPIC_SMPRR_B,
185 		.force	= IPIC_SEFCR,
186 		.bit	= 5,
187 		.prio_mask = 5,
188 	},
189 	[22] = {
190 		.ack	= IPIC_SEPNR,
191 		.mask	= IPIC_SEMSR,
192 		.prio	= IPIC_SMPRR_B,
193 		.force	= IPIC_SEFCR,
194 		.bit	= 6,
195 		.prio_mask = 6,
196 	},
197 	[23] = {
198 		.ack	= IPIC_SEPNR,
199 		.mask	= IPIC_SEMSR,
200 		.prio	= IPIC_SMPRR_B,
201 		.force	= IPIC_SEFCR,
202 		.bit	= 7,
203 		.prio_mask = 7,
204 	},
205 	[32] = {
206 		.mask	= IPIC_SIMSR_H,
207 		.prio	= IPIC_SIPRR_A,
208 		.force	= IPIC_SIFCR_H,
209 		.bit	= 0,
210 		.prio_mask = 0,
211 	},
212 	[33] = {
213 		.mask	= IPIC_SIMSR_H,
214 		.prio	= IPIC_SIPRR_A,
215 		.force	= IPIC_SIFCR_H,
216 		.bit	= 1,
217 		.prio_mask = 1,
218 	},
219 	[34] = {
220 		.mask	= IPIC_SIMSR_H,
221 		.prio	= IPIC_SIPRR_A,
222 		.force	= IPIC_SIFCR_H,
223 		.bit	= 2,
224 		.prio_mask = 2,
225 	},
226 	[35] = {
227 		.mask	= IPIC_SIMSR_H,
228 		.prio	= IPIC_SIPRR_A,
229 		.force	= IPIC_SIFCR_H,
230 		.bit	= 3,
231 		.prio_mask = 3,
232 	},
233 	[36] = {
234 		.mask	= IPIC_SIMSR_H,
235 		.prio	= IPIC_SIPRR_A,
236 		.force	= IPIC_SIFCR_H,
237 		.bit	= 4,
238 		.prio_mask = 4,
239 	},
240 	[37] = {
241 		.mask	= IPIC_SIMSR_H,
242 		.prio	= IPIC_SIPRR_A,
243 		.force	= IPIC_SIFCR_H,
244 		.bit	= 5,
245 		.prio_mask = 5,
246 	},
247 	[38] = {
248 		.mask	= IPIC_SIMSR_H,
249 		.prio	= IPIC_SIPRR_A,
250 		.force	= IPIC_SIFCR_H,
251 		.bit	= 6,
252 		.prio_mask = 6,
253 	},
254 	[39] = {
255 		.mask	= IPIC_SIMSR_H,
256 		.prio	= IPIC_SIPRR_A,
257 		.force	= IPIC_SIFCR_H,
258 		.bit	= 7,
259 		.prio_mask = 7,
260 	},
261 	[40] = {
262 		.mask	= IPIC_SIMSR_H,
263 		.prio	= IPIC_SIPRR_B,
264 		.force	= IPIC_SIFCR_H,
265 		.bit	= 8,
266 		.prio_mask = 0,
267 	},
268 	[41] = {
269 		.mask	= IPIC_SIMSR_H,
270 		.prio	= IPIC_SIPRR_B,
271 		.force	= IPIC_SIFCR_H,
272 		.bit	= 9,
273 		.prio_mask = 1,
274 	},
275 	[42] = {
276 		.mask	= IPIC_SIMSR_H,
277 		.prio	= IPIC_SIPRR_B,
278 		.force	= IPIC_SIFCR_H,
279 		.bit	= 10,
280 		.prio_mask = 2,
281 	},
282 	[43] = {
283 		.mask	= IPIC_SIMSR_H,
284 		.prio	= IPIC_SIPRR_B,
285 		.force	= IPIC_SIFCR_H,
286 		.bit	= 11,
287 		.prio_mask = 3,
288 	},
289 	[44] = {
290 		.mask	= IPIC_SIMSR_H,
291 		.prio	= IPIC_SIPRR_B,
292 		.force	= IPIC_SIFCR_H,
293 		.bit	= 12,
294 		.prio_mask = 4,
295 	},
296 	[45] = {
297 		.mask	= IPIC_SIMSR_H,
298 		.prio	= IPIC_SIPRR_B,
299 		.force	= IPIC_SIFCR_H,
300 		.bit	= 13,
301 		.prio_mask = 5,
302 	},
303 	[46] = {
304 		.mask	= IPIC_SIMSR_H,
305 		.prio	= IPIC_SIPRR_B,
306 		.force	= IPIC_SIFCR_H,
307 		.bit	= 14,
308 		.prio_mask = 6,
309 	},
310 	[47] = {
311 		.mask	= IPIC_SIMSR_H,
312 		.prio	= IPIC_SIPRR_B,
313 		.force	= IPIC_SIFCR_H,
314 		.bit	= 15,
315 		.prio_mask = 7,
316 	},
317 	[48] = {
318 		.mask	= IPIC_SEMSR,
319 		.prio	= IPIC_SMPRR_A,
320 		.force	= IPIC_SEFCR,
321 		.bit	= 0,
322 		.prio_mask = 4,
323 	},
324 	[64] = {
325 		.mask	= IPIC_SIMSR_L,
326 		.prio	= IPIC_SMPRR_A,
327 		.force	= IPIC_SIFCR_L,
328 		.bit	= 0,
329 		.prio_mask = 0,
330 	},
331 	[65] = {
332 		.mask	= IPIC_SIMSR_L,
333 		.prio	= IPIC_SMPRR_A,
334 		.force	= IPIC_SIFCR_L,
335 		.bit	= 1,
336 		.prio_mask = 1,
337 	},
338 	[66] = {
339 		.mask	= IPIC_SIMSR_L,
340 		.prio	= IPIC_SMPRR_A,
341 		.force	= IPIC_SIFCR_L,
342 		.bit	= 2,
343 		.prio_mask = 2,
344 	},
345 	[67] = {
346 		.mask	= IPIC_SIMSR_L,
347 		.prio	= IPIC_SMPRR_A,
348 		.force	= IPIC_SIFCR_L,
349 		.bit	= 3,
350 		.prio_mask = 3,
351 	},
352 	[68] = {
353 		.mask	= IPIC_SIMSR_L,
354 		.prio	= IPIC_SMPRR_B,
355 		.force	= IPIC_SIFCR_L,
356 		.bit	= 4,
357 		.prio_mask = 0,
358 	},
359 	[69] = {
360 		.mask	= IPIC_SIMSR_L,
361 		.prio	= IPIC_SMPRR_B,
362 		.force	= IPIC_SIFCR_L,
363 		.bit	= 5,
364 		.prio_mask = 1,
365 	},
366 	[70] = {
367 		.mask	= IPIC_SIMSR_L,
368 		.prio	= IPIC_SMPRR_B,
369 		.force	= IPIC_SIFCR_L,
370 		.bit	= 6,
371 		.prio_mask = 2,
372 	},
373 	[71] = {
374 		.mask	= IPIC_SIMSR_L,
375 		.prio	= IPIC_SMPRR_B,
376 		.force	= IPIC_SIFCR_L,
377 		.bit	= 7,
378 		.prio_mask = 3,
379 	},
380 	[72] = {
381 		.mask	= IPIC_SIMSR_L,
382 		.prio	= 0,
383 		.force	= IPIC_SIFCR_L,
384 		.bit	= 8,
385 	},
386 	[73] = {
387 		.mask	= IPIC_SIMSR_L,
388 		.prio	= 0,
389 		.force	= IPIC_SIFCR_L,
390 		.bit	= 9,
391 	},
392 	[74] = {
393 		.mask	= IPIC_SIMSR_L,
394 		.prio	= 0,
395 		.force	= IPIC_SIFCR_L,
396 		.bit	= 10,
397 	},
398 	[75] = {
399 		.mask	= IPIC_SIMSR_L,
400 		.prio	= 0,
401 		.force	= IPIC_SIFCR_L,
402 		.bit	= 11,
403 	},
404 	[76] = {
405 		.mask	= IPIC_SIMSR_L,
406 		.prio	= 0,
407 		.force	= IPIC_SIFCR_L,
408 		.bit	= 12,
409 	},
410 	[77] = {
411 		.mask	= IPIC_SIMSR_L,
412 		.prio	= 0,
413 		.force	= IPIC_SIFCR_L,
414 		.bit	= 13,
415 	},
416 	[78] = {
417 		.mask	= IPIC_SIMSR_L,
418 		.prio	= 0,
419 		.force	= IPIC_SIFCR_L,
420 		.bit	= 14,
421 	},
422 	[79] = {
423 		.mask	= IPIC_SIMSR_L,
424 		.prio	= 0,
425 		.force	= IPIC_SIFCR_L,
426 		.bit	= 15,
427 	},
428 	[80] = {
429 		.mask	= IPIC_SIMSR_L,
430 		.prio	= 0,
431 		.force	= IPIC_SIFCR_L,
432 		.bit	= 16,
433 	},
434 	[81] = {
435 		.mask	= IPIC_SIMSR_L,
436 		.prio	= 0,
437 		.force	= IPIC_SIFCR_L,
438 		.bit	= 17,
439 	},
440 	[82] = {
441 		.mask	= IPIC_SIMSR_L,
442 		.prio	= 0,
443 		.force	= IPIC_SIFCR_L,
444 		.bit	= 18,
445 	},
446 	[83] = {
447 		.mask	= IPIC_SIMSR_L,
448 		.prio	= 0,
449 		.force	= IPIC_SIFCR_L,
450 		.bit	= 19,
451 	},
452 	[84] = {
453 		.mask	= IPIC_SIMSR_L,
454 		.prio	= 0,
455 		.force	= IPIC_SIFCR_L,
456 		.bit	= 20,
457 	},
458 	[85] = {
459 		.mask	= IPIC_SIMSR_L,
460 		.prio	= 0,
461 		.force	= IPIC_SIFCR_L,
462 		.bit	= 21,
463 	},
464 	[86] = {
465 		.mask	= IPIC_SIMSR_L,
466 		.prio	= 0,
467 		.force	= IPIC_SIFCR_L,
468 		.bit	= 22,
469 	},
470 	[87] = {
471 		.mask	= IPIC_SIMSR_L,
472 		.prio	= 0,
473 		.force	= IPIC_SIFCR_L,
474 		.bit	= 23,
475 	},
476 	[88] = {
477 		.mask	= IPIC_SIMSR_L,
478 		.prio	= 0,
479 		.force	= IPIC_SIFCR_L,
480 		.bit	= 24,
481 	},
482 	[89] = {
483 		.mask	= IPIC_SIMSR_L,
484 		.prio	= 0,
485 		.force	= IPIC_SIFCR_L,
486 		.bit	= 25,
487 	},
488 	[90] = {
489 		.mask	= IPIC_SIMSR_L,
490 		.prio	= 0,
491 		.force	= IPIC_SIFCR_L,
492 		.bit	= 26,
493 	},
494 	[91] = {
495 		.mask	= IPIC_SIMSR_L,
496 		.prio	= 0,
497 		.force	= IPIC_SIFCR_L,
498 		.bit	= 27,
499 	},
500 	[94] = {
501 		.mask	= IPIC_SIMSR_L,
502 		.prio	= 0,
503 		.force	= IPIC_SIFCR_L,
504 		.bit	= 30,
505 	},
506 };
507 
508 static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg)
509 {
510 	return in_be32(base + (reg >> 2));
511 }
512 
513 static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 value)
514 {
515 	out_be32(base + (reg >> 2), value);
516 }
517 
518 static inline struct ipic * ipic_from_irq(unsigned int virq)
519 {
520 	return primary_ipic;
521 }
522 
523 #define ipic_irq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
524 
525 static void ipic_unmask_irq(unsigned int virq)
526 {
527 	struct ipic *ipic = ipic_from_irq(virq);
528 	unsigned int src = ipic_irq_to_hw(virq);
529 	unsigned long flags;
530 	u32 temp;
531 
532 	spin_lock_irqsave(&ipic_lock, flags);
533 
534 	temp = ipic_read(ipic->regs, ipic_info[src].mask);
535 	temp |= (1 << (31 - ipic_info[src].bit));
536 	ipic_write(ipic->regs, ipic_info[src].mask, temp);
537 
538 	spin_unlock_irqrestore(&ipic_lock, flags);
539 }
540 
541 static void ipic_mask_irq(unsigned int virq)
542 {
543 	struct ipic *ipic = ipic_from_irq(virq);
544 	unsigned int src = ipic_irq_to_hw(virq);
545 	unsigned long flags;
546 	u32 temp;
547 
548 	spin_lock_irqsave(&ipic_lock, flags);
549 
550 	temp = ipic_read(ipic->regs, ipic_info[src].mask);
551 	temp &= ~(1 << (31 - ipic_info[src].bit));
552 	ipic_write(ipic->regs, ipic_info[src].mask, temp);
553 
554 	/* mb() can't guarantee that masking is finished.  But it does finish
555 	 * for nearly all cases. */
556 	mb();
557 
558 	spin_unlock_irqrestore(&ipic_lock, flags);
559 }
560 
561 static void ipic_ack_irq(unsigned int virq)
562 {
563 	struct ipic *ipic = ipic_from_irq(virq);
564 	unsigned int src = ipic_irq_to_hw(virq);
565 	unsigned long flags;
566 	u32 temp;
567 
568 	spin_lock_irqsave(&ipic_lock, flags);
569 
570 	temp = ipic_read(ipic->regs, ipic_info[src].ack);
571 	temp |= (1 << (31 - ipic_info[src].bit));
572 	ipic_write(ipic->regs, ipic_info[src].ack, temp);
573 
574 	/* mb() can't guarantee that ack is finished.  But it does finish
575 	 * for nearly all cases. */
576 	mb();
577 
578 	spin_unlock_irqrestore(&ipic_lock, flags);
579 }
580 
581 static void ipic_mask_irq_and_ack(unsigned int virq)
582 {
583 	struct ipic *ipic = ipic_from_irq(virq);
584 	unsigned int src = ipic_irq_to_hw(virq);
585 	unsigned long flags;
586 	u32 temp;
587 
588 	spin_lock_irqsave(&ipic_lock, flags);
589 
590 	temp = ipic_read(ipic->regs, ipic_info[src].mask);
591 	temp &= ~(1 << (31 - ipic_info[src].bit));
592 	ipic_write(ipic->regs, ipic_info[src].mask, temp);
593 
594 	temp = ipic_read(ipic->regs, ipic_info[src].ack);
595 	temp |= (1 << (31 - ipic_info[src].bit));
596 	ipic_write(ipic->regs, ipic_info[src].ack, temp);
597 
598 	/* mb() can't guarantee that ack is finished.  But it does finish
599 	 * for nearly all cases. */
600 	mb();
601 
602 	spin_unlock_irqrestore(&ipic_lock, flags);
603 }
604 
605 static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
606 {
607 	struct ipic *ipic = ipic_from_irq(virq);
608 	unsigned int src = ipic_irq_to_hw(virq);
609 	struct irq_desc *desc = get_irq_desc(virq);
610 	unsigned int vold, vnew, edibit;
611 
612 	if (flow_type == IRQ_TYPE_NONE)
613 		flow_type = IRQ_TYPE_LEVEL_LOW;
614 
615 	/* ipic supports only low assertion and high-to-low change senses
616 	 */
617 	if (!(flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))) {
618 		printk(KERN_ERR "ipic: sense type 0x%x not supported\n",
619 			flow_type);
620 		return -EINVAL;
621 	}
622 	/* ipic supports only edge mode on external interrupts */
623 	if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) {
624 		printk(KERN_ERR "ipic: edge sense not supported on internal "
625 				"interrupts\n");
626 		return -EINVAL;
627 	}
628 
629 	desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
630 	desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
631 	if (flow_type & IRQ_TYPE_LEVEL_LOW)  {
632 		desc->status |= IRQ_LEVEL;
633 		desc->handle_irq = handle_level_irq;
634 		desc->chip = &ipic_level_irq_chip;
635 	} else {
636 		desc->handle_irq = handle_edge_irq;
637 		desc->chip = &ipic_edge_irq_chip;
638 	}
639 
640 	/* only EXT IRQ senses are programmable on ipic
641 	 * internal IRQ senses are LEVEL_LOW
642 	 */
643 	if (src == IPIC_IRQ_EXT0)
644 		edibit = 15;
645 	else
646 		if (src >= IPIC_IRQ_EXT1 && src <= IPIC_IRQ_EXT7)
647 			edibit = (14 - (src - IPIC_IRQ_EXT1));
648 		else
649 			return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL;
650 
651 	vold = ipic_read(ipic->regs, IPIC_SECNR);
652 	if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) {
653 		vnew = vold | (1 << edibit);
654 	} else {
655 		vnew = vold & ~(1 << edibit);
656 	}
657 	if (vold != vnew)
658 		ipic_write(ipic->regs, IPIC_SECNR, vnew);
659 	return 0;
660 }
661 
662 /* level interrupts and edge interrupts have different ack operations */
663 static struct irq_chip ipic_level_irq_chip = {
664 	.typename	= " IPIC  ",
665 	.unmask		= ipic_unmask_irq,
666 	.mask		= ipic_mask_irq,
667 	.mask_ack	= ipic_mask_irq,
668 	.set_type	= ipic_set_irq_type,
669 };
670 
671 static struct irq_chip ipic_edge_irq_chip = {
672 	.typename	= " IPIC  ",
673 	.unmask		= ipic_unmask_irq,
674 	.mask		= ipic_mask_irq,
675 	.mask_ack	= ipic_mask_irq_and_ack,
676 	.ack		= ipic_ack_irq,
677 	.set_type	= ipic_set_irq_type,
678 };
679 
680 static int ipic_host_match(struct irq_host *h, struct device_node *node)
681 {
682 	/* Exact match, unless ipic node is NULL */
683 	return h->of_node == NULL || h->of_node == node;
684 }
685 
686 static int ipic_host_map(struct irq_host *h, unsigned int virq,
687 			 irq_hw_number_t hw)
688 {
689 	struct ipic *ipic = h->host_data;
690 
691 	set_irq_chip_data(virq, ipic);
692 	set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
693 
694 	/* Set default irq type */
695 	set_irq_type(virq, IRQ_TYPE_NONE);
696 
697 	return 0;
698 }
699 
700 static int ipic_host_xlate(struct irq_host *h, struct device_node *ct,
701 			   u32 *intspec, unsigned int intsize,
702 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
703 
704 {
705 	/* interrupt sense values coming from the device tree equal either
706 	 * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change)
707 	 */
708 	*out_hwirq = intspec[0];
709 	if (intsize > 1)
710 		*out_flags = intspec[1];
711 	else
712 		*out_flags = IRQ_TYPE_NONE;
713 	return 0;
714 }
715 
716 static struct irq_host_ops ipic_host_ops = {
717 	.match	= ipic_host_match,
718 	.map	= ipic_host_map,
719 	.xlate	= ipic_host_xlate,
720 };
721 
722 struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
723 {
724 	struct ipic	*ipic;
725 	struct resource res;
726 	u32 temp = 0, ret;
727 
728 	ipic = alloc_bootmem(sizeof(struct ipic));
729 	if (ipic == NULL)
730 		return NULL;
731 
732 	memset(ipic, 0, sizeof(struct ipic));
733 
734 	ipic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR,
735 				       NR_IPIC_INTS,
736 				       &ipic_host_ops, 0);
737 	if (ipic->irqhost == NULL) {
738 		of_node_put(node);
739 		return NULL;
740 	}
741 
742 	ret = of_address_to_resource(node, 0, &res);
743 	if (ret) {
744 		of_node_put(node);
745 		return NULL;
746 	}
747 
748 	ipic->regs = ioremap(res.start, res.end - res.start + 1);
749 
750 	ipic->irqhost->host_data = ipic;
751 
752 	/* init hw */
753 	ipic_write(ipic->regs, IPIC_SICNR, 0x0);
754 
755 	/* default priority scheme is grouped. If spread mode is required
756 	 * configure SICFR accordingly */
757 	if (flags & IPIC_SPREADMODE_GRP_A)
758 		temp |= SICFR_IPSA;
759 	if (flags & IPIC_SPREADMODE_GRP_B)
760 		temp |= SICFR_IPSB;
761 	if (flags & IPIC_SPREADMODE_GRP_C)
762 		temp |= SICFR_IPSC;
763 	if (flags & IPIC_SPREADMODE_GRP_D)
764 		temp |= SICFR_IPSD;
765 	if (flags & IPIC_SPREADMODE_MIX_A)
766 		temp |= SICFR_MPSA;
767 	if (flags & IPIC_SPREADMODE_MIX_B)
768 		temp |= SICFR_MPSB;
769 
770 	ipic_write(ipic->regs, IPIC_SICFR, temp);
771 
772 	/* handle MCP route */
773 	temp = 0;
774 	if (flags & IPIC_DISABLE_MCP_OUT)
775 		temp = SERCR_MCPR;
776 	ipic_write(ipic->regs, IPIC_SERCR, temp);
777 
778 	/* handle routing of IRQ0 to MCP */
779 	temp = ipic_read(ipic->regs, IPIC_SEMSR);
780 
781 	if (flags & IPIC_IRQ0_MCP)
782 		temp |= SEMSR_SIRQ0;
783 	else
784 		temp &= ~SEMSR_SIRQ0;
785 
786 	ipic_write(ipic->regs, IPIC_SEMSR, temp);
787 
788 	primary_ipic = ipic;
789 	irq_set_default_host(primary_ipic->irqhost);
790 
791 	printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS,
792 			primary_ipic->regs);
793 
794 	return ipic;
795 }
796 
797 int ipic_set_priority(unsigned int virq, unsigned int priority)
798 {
799 	struct ipic *ipic = ipic_from_irq(virq);
800 	unsigned int src = ipic_irq_to_hw(virq);
801 	u32 temp;
802 
803 	if (priority > 7)
804 		return -EINVAL;
805 	if (src > 127)
806 		return -EINVAL;
807 	if (ipic_info[src].prio == 0)
808 		return -EINVAL;
809 
810 	temp = ipic_read(ipic->regs, ipic_info[src].prio);
811 
812 	if (priority < 4) {
813 		temp &= ~(0x7 << (20 + (3 - priority) * 3));
814 		temp |= ipic_info[src].prio_mask << (20 + (3 - priority) * 3);
815 	} else {
816 		temp &= ~(0x7 << (4 + (7 - priority) * 3));
817 		temp |= ipic_info[src].prio_mask << (4 + (7 - priority) * 3);
818 	}
819 
820 	ipic_write(ipic->regs, ipic_info[src].prio, temp);
821 
822 	return 0;
823 }
824 
825 void ipic_set_highest_priority(unsigned int virq)
826 {
827 	struct ipic *ipic = ipic_from_irq(virq);
828 	unsigned int src = ipic_irq_to_hw(virq);
829 	u32 temp;
830 
831 	temp = ipic_read(ipic->regs, IPIC_SICFR);
832 
833 	/* clear and set HPI */
834 	temp &= 0x7f000000;
835 	temp |= (src & 0x7f) << 24;
836 
837 	ipic_write(ipic->regs, IPIC_SICFR, temp);
838 }
839 
840 void ipic_set_default_priority(void)
841 {
842 	ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_PRIORITY_DEFAULT);
843 	ipic_write(primary_ipic->regs, IPIC_SIPRR_B, IPIC_PRIORITY_DEFAULT);
844 	ipic_write(primary_ipic->regs, IPIC_SIPRR_C, IPIC_PRIORITY_DEFAULT);
845 	ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_PRIORITY_DEFAULT);
846 	ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_PRIORITY_DEFAULT);
847 	ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_PRIORITY_DEFAULT);
848 }
849 
850 void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq)
851 {
852 	struct ipic *ipic = primary_ipic;
853 	u32 temp;
854 
855 	temp = ipic_read(ipic->regs, IPIC_SERMR);
856 	temp |= (1 << (31 - mcp_irq));
857 	ipic_write(ipic->regs, IPIC_SERMR, temp);
858 }
859 
860 void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq)
861 {
862 	struct ipic *ipic = primary_ipic;
863 	u32 temp;
864 
865 	temp = ipic_read(ipic->regs, IPIC_SERMR);
866 	temp &= (1 << (31 - mcp_irq));
867 	ipic_write(ipic->regs, IPIC_SERMR, temp);
868 }
869 
870 u32 ipic_get_mcp_status(void)
871 {
872 	return ipic_read(primary_ipic->regs, IPIC_SERMR);
873 }
874 
875 void ipic_clear_mcp_status(u32 mask)
876 {
877 	ipic_write(primary_ipic->regs, IPIC_SERMR, mask);
878 }
879 
880 /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
881 unsigned int ipic_get_irq(void)
882 {
883 	int irq;
884 
885 	BUG_ON(primary_ipic == NULL);
886 
887 #define IPIC_SIVCR_VECTOR_MASK	0x7f
888 	irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & IPIC_SIVCR_VECTOR_MASK;
889 
890 	if (irq == 0)    /* 0 --> no irq is pending */
891 		return NO_IRQ;
892 
893 	return irq_linear_revmap(primary_ipic->irqhost, irq);
894 }
895 
896 static struct sysdev_class ipic_sysclass = {
897 	.name = "ipic",
898 };
899 
900 static struct sys_device device_ipic = {
901 	.id		= 0,
902 	.cls		= &ipic_sysclass,
903 };
904 
905 static int __init init_ipic_sysfs(void)
906 {
907 	int rc;
908 
909 	if (!primary_ipic->regs)
910 		return -ENODEV;
911 	printk(KERN_DEBUG "Registering ipic with sysfs...\n");
912 
913 	rc = sysdev_class_register(&ipic_sysclass);
914 	if (rc) {
915 		printk(KERN_ERR "Failed registering ipic sys class\n");
916 		return -ENODEV;
917 	}
918 	rc = sysdev_register(&device_ipic);
919 	if (rc) {
920 		printk(KERN_ERR "Failed registering ipic sys device\n");
921 		return -ENODEV;
922 	}
923 	return 0;
924 }
925 
926 subsys_initcall(init_ipic_sysfs);
927