Linux Audio

Check our new training course

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