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