• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * S3C24XX IRQ handling
3  *
4  * Copyright (c) 2003-2004 Simtec Electronics
5  *	Ben Dooks <ben@simtec.co.uk>
6  * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17 */
18 
19 #include <linux/init.h>
20 #include <linux/slab.h>
21 #include <linux/module.h>
22 #include <linux/io.h>
23 #include <linux/err.h>
24 #include <linux/interrupt.h>
25 #include <linux/ioport.h>
26 #include <linux/device.h>
27 #include <linux/irqdomain.h>
28 #include <linux/irqchip/chained_irq.h>
29 #include <linux/of.h>
30 #include <linux/of_irq.h>
31 #include <linux/of_address.h>
32 
33 #include <asm/exception.h>
34 #include <asm/mach/irq.h>
35 
36 #include <mach/regs-irq.h>
37 #include <mach/regs-gpio.h>
38 
39 #include <plat/cpu.h>
40 #include <plat/regs-irqtype.h>
41 #include <plat/pm.h>
42 
43 #include "irqchip.h"
44 
45 #define S3C_IRQTYPE_NONE	0
46 #define S3C_IRQTYPE_EINT	1
47 #define S3C_IRQTYPE_EDGE	2
48 #define S3C_IRQTYPE_LEVEL	3
49 
50 struct s3c_irq_data {
51 	unsigned int type;
52 	unsigned long offset;
53 	unsigned long parent_irq;
54 
55 	/* data gets filled during init */
56 	struct s3c_irq_intc *intc;
57 	unsigned long sub_bits;
58 	struct s3c_irq_intc *sub_intc;
59 };
60 
61 /*
62  * Sructure holding the controller data
63  * @reg_pending		register holding pending irqs
64  * @reg_intpnd		special register intpnd in main intc
65  * @reg_mask		mask register
66  * @domain		irq_domain of the controller
67  * @parent		parent controller for ext and sub irqs
68  * @irqs		irq-data, always s3c_irq_data[32]
69  */
70 struct s3c_irq_intc {
71 	void __iomem		*reg_pending;
72 	void __iomem		*reg_intpnd;
73 	void __iomem		*reg_mask;
74 	struct irq_domain	*domain;
75 	struct s3c_irq_intc	*parent;
76 	struct s3c_irq_data	*irqs;
77 };
78 
79 /*
80  * Array holding pointers to the global controller structs
81  * [0] ... main_intc
82  * [1] ... sub_intc
83  * [2] ... main_intc2 on s3c2416
84  */
85 static struct s3c_irq_intc *s3c_intc[3];
86 
s3c_irq_mask(struct irq_data * data)87 static void s3c_irq_mask(struct irq_data *data)
88 {
89 	struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
90 	struct s3c_irq_intc *intc = irq_data->intc;
91 	struct s3c_irq_intc *parent_intc = intc->parent;
92 	struct s3c_irq_data *parent_data;
93 	unsigned long mask;
94 	unsigned int irqno;
95 
96 	mask = __raw_readl(intc->reg_mask);
97 	mask |= (1UL << irq_data->offset);
98 	__raw_writel(mask, intc->reg_mask);
99 
100 	if (parent_intc) {
101 		parent_data = &parent_intc->irqs[irq_data->parent_irq];
102 
103 		/* check to see if we need to mask the parent IRQ
104 		 * The parent_irq is always in main_intc, so the hwirq
105 		 * for find_mapping does not need an offset in any case.
106 		 */
107 		if ((mask & parent_data->sub_bits) == parent_data->sub_bits) {
108 			irqno = irq_find_mapping(parent_intc->domain,
109 					 irq_data->parent_irq);
110 			s3c_irq_mask(irq_get_irq_data(irqno));
111 		}
112 	}
113 }
114 
s3c_irq_unmask(struct irq_data * data)115 static void s3c_irq_unmask(struct irq_data *data)
116 {
117 	struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
118 	struct s3c_irq_intc *intc = irq_data->intc;
119 	struct s3c_irq_intc *parent_intc = intc->parent;
120 	unsigned long mask;
121 	unsigned int irqno;
122 
123 	mask = __raw_readl(intc->reg_mask);
124 	mask &= ~(1UL << irq_data->offset);
125 	__raw_writel(mask, intc->reg_mask);
126 
127 	if (parent_intc) {
128 		irqno = irq_find_mapping(parent_intc->domain,
129 					 irq_data->parent_irq);
130 		s3c_irq_unmask(irq_get_irq_data(irqno));
131 	}
132 }
133 
s3c_irq_ack(struct irq_data * data)134 static inline void s3c_irq_ack(struct irq_data *data)
135 {
136 	struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
137 	struct s3c_irq_intc *intc = irq_data->intc;
138 	unsigned long bitval = 1UL << irq_data->offset;
139 
140 	__raw_writel(bitval, intc->reg_pending);
141 	if (intc->reg_intpnd)
142 		__raw_writel(bitval, intc->reg_intpnd);
143 }
144 
s3c_irq_type(struct irq_data * data,unsigned int type)145 static int s3c_irq_type(struct irq_data *data, unsigned int type)
146 {
147 	switch (type) {
148 	case IRQ_TYPE_NONE:
149 		break;
150 	case IRQ_TYPE_EDGE_RISING:
151 	case IRQ_TYPE_EDGE_FALLING:
152 	case IRQ_TYPE_EDGE_BOTH:
153 		irq_set_handler(data->irq, handle_edge_irq);
154 		break;
155 	case IRQ_TYPE_LEVEL_LOW:
156 	case IRQ_TYPE_LEVEL_HIGH:
157 		irq_set_handler(data->irq, handle_level_irq);
158 		break;
159 	default:
160 		pr_err("No such irq type %d", type);
161 		return -EINVAL;
162 	}
163 
164 	return 0;
165 }
166 
s3c_irqext_type_set(void __iomem * gpcon_reg,void __iomem * extint_reg,unsigned long gpcon_offset,unsigned long extint_offset,unsigned int type)167 static int s3c_irqext_type_set(void __iomem *gpcon_reg,
168 			       void __iomem *extint_reg,
169 			       unsigned long gpcon_offset,
170 			       unsigned long extint_offset,
171 			       unsigned int type)
172 {
173 	unsigned long newvalue = 0, value;
174 
175 	/* Set the GPIO to external interrupt mode */
176 	value = __raw_readl(gpcon_reg);
177 	value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
178 	__raw_writel(value, gpcon_reg);
179 
180 	/* Set the external interrupt to pointed trigger type */
181 	switch (type)
182 	{
183 		case IRQ_TYPE_NONE:
184 			pr_warn("No edge setting!\n");
185 			break;
186 
187 		case IRQ_TYPE_EDGE_RISING:
188 			newvalue = S3C2410_EXTINT_RISEEDGE;
189 			break;
190 
191 		case IRQ_TYPE_EDGE_FALLING:
192 			newvalue = S3C2410_EXTINT_FALLEDGE;
193 			break;
194 
195 		case IRQ_TYPE_EDGE_BOTH:
196 			newvalue = S3C2410_EXTINT_BOTHEDGE;
197 			break;
198 
199 		case IRQ_TYPE_LEVEL_LOW:
200 			newvalue = S3C2410_EXTINT_LOWLEV;
201 			break;
202 
203 		case IRQ_TYPE_LEVEL_HIGH:
204 			newvalue = S3C2410_EXTINT_HILEV;
205 			break;
206 
207 		default:
208 			pr_err("No such irq type %d", type);
209 			return -EINVAL;
210 	}
211 
212 	value = __raw_readl(extint_reg);
213 	value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
214 	__raw_writel(value, extint_reg);
215 
216 	return 0;
217 }
218 
s3c_irqext_type(struct irq_data * data,unsigned int type)219 static int s3c_irqext_type(struct irq_data *data, unsigned int type)
220 {
221 	void __iomem *extint_reg;
222 	void __iomem *gpcon_reg;
223 	unsigned long gpcon_offset, extint_offset;
224 
225 	if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
226 		gpcon_reg = S3C2410_GPFCON;
227 		extint_reg = S3C24XX_EXTINT0;
228 		gpcon_offset = (data->hwirq) * 2;
229 		extint_offset = (data->hwirq) * 4;
230 	} else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
231 		gpcon_reg = S3C2410_GPGCON;
232 		extint_reg = S3C24XX_EXTINT1;
233 		gpcon_offset = (data->hwirq - 8) * 2;
234 		extint_offset = (data->hwirq - 8) * 4;
235 	} else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
236 		gpcon_reg = S3C2410_GPGCON;
237 		extint_reg = S3C24XX_EXTINT2;
238 		gpcon_offset = (data->hwirq - 8) * 2;
239 		extint_offset = (data->hwirq - 16) * 4;
240 	} else {
241 		return -EINVAL;
242 	}
243 
244 	return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
245 				   extint_offset, type);
246 }
247 
s3c_irqext0_type(struct irq_data * data,unsigned int type)248 static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
249 {
250 	void __iomem *extint_reg;
251 	void __iomem *gpcon_reg;
252 	unsigned long gpcon_offset, extint_offset;
253 
254 	if ((data->hwirq >= 0) && (data->hwirq <= 3)) {
255 		gpcon_reg = S3C2410_GPFCON;
256 		extint_reg = S3C24XX_EXTINT0;
257 		gpcon_offset = (data->hwirq) * 2;
258 		extint_offset = (data->hwirq) * 4;
259 	} else {
260 		return -EINVAL;
261 	}
262 
263 	return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
264 				   extint_offset, type);
265 }
266 
267 static struct irq_chip s3c_irq_chip = {
268 	.name		= "s3c",
269 	.irq_ack	= s3c_irq_ack,
270 	.irq_mask	= s3c_irq_mask,
271 	.irq_unmask	= s3c_irq_unmask,
272 	.irq_set_type	= s3c_irq_type,
273 	.irq_set_wake	= s3c_irq_wake
274 };
275 
276 static struct irq_chip s3c_irq_level_chip = {
277 	.name		= "s3c-level",
278 	.irq_mask	= s3c_irq_mask,
279 	.irq_unmask	= s3c_irq_unmask,
280 	.irq_ack	= s3c_irq_ack,
281 	.irq_set_type	= s3c_irq_type,
282 };
283 
284 static struct irq_chip s3c_irqext_chip = {
285 	.name		= "s3c-ext",
286 	.irq_mask	= s3c_irq_mask,
287 	.irq_unmask	= s3c_irq_unmask,
288 	.irq_ack	= s3c_irq_ack,
289 	.irq_set_type	= s3c_irqext_type,
290 	.irq_set_wake	= s3c_irqext_wake
291 };
292 
293 static struct irq_chip s3c_irq_eint0t4 = {
294 	.name		= "s3c-ext0",
295 	.irq_ack	= s3c_irq_ack,
296 	.irq_mask	= s3c_irq_mask,
297 	.irq_unmask	= s3c_irq_unmask,
298 	.irq_set_wake	= s3c_irq_wake,
299 	.irq_set_type	= s3c_irqext0_type,
300 };
301 
s3c_irq_demux(unsigned int irq,struct irq_desc * desc)302 static void s3c_irq_demux(unsigned int irq, struct irq_desc *desc)
303 {
304 	struct irq_chip *chip = irq_desc_get_chip(desc);
305 	struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc);
306 	struct s3c_irq_intc *intc = irq_data->intc;
307 	struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
308 	unsigned long src;
309 	unsigned long msk;
310 	unsigned int n;
311 	unsigned int offset;
312 
313 	/* we're using individual domains for the non-dt case
314 	 * and one big domain for the dt case where the subintc
315 	 * starts at hwirq number 32.
316 	 */
317 	offset = (intc->domain->of_node) ? 32 : 0;
318 
319 	chained_irq_enter(chip, desc);
320 
321 	src = __raw_readl(sub_intc->reg_pending);
322 	msk = __raw_readl(sub_intc->reg_mask);
323 
324 	src &= ~msk;
325 	src &= irq_data->sub_bits;
326 
327 	while (src) {
328 		n = __ffs(src);
329 		src &= ~(1 << n);
330 		irq = irq_find_mapping(sub_intc->domain, offset + n);
331 		generic_handle_irq(irq);
332 	}
333 
334 	chained_irq_exit(chip, desc);
335 }
336 
s3c24xx_handle_intc(struct s3c_irq_intc * intc,struct pt_regs * regs,int intc_offset)337 static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
338 				      struct pt_regs *regs, int intc_offset)
339 {
340 	int pnd;
341 	int offset;
342 	int irq;
343 
344 	pnd = __raw_readl(intc->reg_intpnd);
345 	if (!pnd)
346 		return false;
347 
348 	/* non-dt machines use individual domains */
349 	if (!intc->domain->of_node)
350 		intc_offset = 0;
351 
352 	/* We have a problem that the INTOFFSET register does not always
353 	 * show one interrupt. Occasionally we get two interrupts through
354 	 * the prioritiser, and this causes the INTOFFSET register to show
355 	 * what looks like the logical-or of the two interrupt numbers.
356 	 *
357 	 * Thanks to Klaus, Shannon, et al for helping to debug this problem
358 	 */
359 	offset = __raw_readl(intc->reg_intpnd + 4);
360 
361 	/* Find the bit manually, when the offset is wrong.
362 	 * The pending register only ever contains the one bit of the next
363 	 * interrupt to handle.
364 	 */
365 	if (!(pnd & (1 << offset)))
366 		offset =  __ffs(pnd);
367 
368 	irq = irq_find_mapping(intc->domain, intc_offset + offset);
369 	handle_IRQ(irq, regs);
370 	return true;
371 }
372 
s3c24xx_handle_irq(struct pt_regs * regs)373 asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs)
374 {
375 	do {
376 		if (likely(s3c_intc[0]))
377 			if (s3c24xx_handle_intc(s3c_intc[0], regs, 0))
378 				continue;
379 
380 		if (s3c_intc[2])
381 			if (s3c24xx_handle_intc(s3c_intc[2], regs, 64))
382 				continue;
383 
384 		break;
385 	} while (1);
386 }
387 
388 #ifdef CONFIG_FIQ
389 /**
390  * s3c24xx_set_fiq - set the FIQ routing
391  * @irq: IRQ number to route to FIQ on processor.
392  * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
393  *
394  * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
395  * @on is true, the @irq is checked to see if it can be routed and the
396  * interrupt controller updated to route the IRQ. If @on is false, the FIQ
397  * routing is cleared, regardless of which @irq is specified.
398  */
s3c24xx_set_fiq(unsigned int irq,bool on)399 int s3c24xx_set_fiq(unsigned int irq, bool on)
400 {
401 	u32 intmod;
402 	unsigned offs;
403 
404 	if (on) {
405 		offs = irq - FIQ_START;
406 		if (offs > 31)
407 			return -EINVAL;
408 
409 		intmod = 1 << offs;
410 	} else {
411 		intmod = 0;
412 	}
413 
414 	__raw_writel(intmod, S3C2410_INTMOD);
415 	return 0;
416 }
417 
418 EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
419 #endif
420 
s3c24xx_irq_map(struct irq_domain * h,unsigned int virq,irq_hw_number_t hw)421 static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
422 							irq_hw_number_t hw)
423 {
424 	struct s3c_irq_intc *intc = h->host_data;
425 	struct s3c_irq_data *irq_data = &intc->irqs[hw];
426 	struct s3c_irq_intc *parent_intc;
427 	struct s3c_irq_data *parent_irq_data;
428 	unsigned int irqno;
429 
430 	/* attach controller pointer to irq_data */
431 	irq_data->intc = intc;
432 	irq_data->offset = hw;
433 
434 	parent_intc = intc->parent;
435 
436 	/* set handler and flags */
437 	switch (irq_data->type) {
438 	case S3C_IRQTYPE_NONE:
439 		return 0;
440 	case S3C_IRQTYPE_EINT:
441 		/* On the S3C2412, the EINT0to3 have a parent irq
442 		 * but need the s3c_irq_eint0t4 chip
443 		 */
444 		if (parent_intc && (!soc_is_s3c2412() || hw >= 4))
445 			irq_set_chip_and_handler(virq, &s3c_irqext_chip,
446 						 handle_edge_irq);
447 		else
448 			irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
449 						 handle_edge_irq);
450 		break;
451 	case S3C_IRQTYPE_EDGE:
452 		if (parent_intc || intc->reg_pending == S3C2416_SRCPND2)
453 			irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
454 						 handle_edge_irq);
455 		else
456 			irq_set_chip_and_handler(virq, &s3c_irq_chip,
457 						 handle_edge_irq);
458 		break;
459 	case S3C_IRQTYPE_LEVEL:
460 		if (parent_intc)
461 			irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
462 						 handle_level_irq);
463 		else
464 			irq_set_chip_and_handler(virq, &s3c_irq_chip,
465 						 handle_level_irq);
466 		break;
467 	default:
468 		pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
469 		return -EINVAL;
470 	}
471 
472 	irq_set_chip_data(virq, irq_data);
473 
474 	set_irq_flags(virq, IRQF_VALID);
475 
476 	if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) {
477 		if (irq_data->parent_irq > 31) {
478 			pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
479 			       irq_data->parent_irq);
480 			goto err;
481 		}
482 
483 		parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
484 		parent_irq_data->sub_intc = intc;
485 		parent_irq_data->sub_bits |= (1UL << hw);
486 
487 		/* attach the demuxer to the parent irq */
488 		irqno = irq_find_mapping(parent_intc->domain,
489 					 irq_data->parent_irq);
490 		if (!irqno) {
491 			pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
492 			       irq_data->parent_irq);
493 			goto err;
494 		}
495 		irq_set_chained_handler(irqno, s3c_irq_demux);
496 	}
497 
498 	return 0;
499 
500 err:
501 	set_irq_flags(virq, 0);
502 
503 	/* the only error can result from bad mapping data*/
504 	return -EINVAL;
505 }
506 
507 static struct irq_domain_ops s3c24xx_irq_ops = {
508 	.map = s3c24xx_irq_map,
509 	.xlate = irq_domain_xlate_twocell,
510 };
511 
s3c24xx_clear_intc(struct s3c_irq_intc * intc)512 static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
513 {
514 	void __iomem *reg_source;
515 	unsigned long pend;
516 	unsigned long last;
517 	int i;
518 
519 	/* if intpnd is set, read the next pending irq from there */
520 	reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending;
521 
522 	last = 0;
523 	for (i = 0; i < 4; i++) {
524 		pend = __raw_readl(reg_source);
525 
526 		if (pend == 0 || pend == last)
527 			break;
528 
529 		__raw_writel(pend, intc->reg_pending);
530 		if (intc->reg_intpnd)
531 			__raw_writel(pend, intc->reg_intpnd);
532 
533 		pr_info("irq: clearing pending status %08x\n", (int)pend);
534 		last = pend;
535 	}
536 }
537 
s3c24xx_init_intc(struct device_node * np,struct s3c_irq_data * irq_data,struct s3c_irq_intc * parent,unsigned long address)538 static struct s3c_irq_intc * __init s3c24xx_init_intc(struct device_node *np,
539 				       struct s3c_irq_data *irq_data,
540 				       struct s3c_irq_intc *parent,
541 				       unsigned long address)
542 {
543 	struct s3c_irq_intc *intc;
544 	void __iomem *base = (void *)0xf6000000; /* static mapping */
545 	int irq_num;
546 	int irq_start;
547 	int ret;
548 
549 	intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
550 	if (!intc)
551 		return ERR_PTR(-ENOMEM);
552 
553 	intc->irqs = irq_data;
554 
555 	if (parent)
556 		intc->parent = parent;
557 
558 	/* select the correct data for the controller.
559 	 * Need to hard code the irq num start and offset
560 	 * to preserve the static mapping for now
561 	 */
562 	switch (address) {
563 	case 0x4a000000:
564 		pr_debug("irq: found main intc\n");
565 		intc->reg_pending = base;
566 		intc->reg_mask = base + 0x08;
567 		intc->reg_intpnd = base + 0x10;
568 		irq_num = 32;
569 		irq_start = S3C2410_IRQ(0);
570 		break;
571 	case 0x4a000018:
572 		pr_debug("irq: found subintc\n");
573 		intc->reg_pending = base + 0x18;
574 		intc->reg_mask = base + 0x1c;
575 		irq_num = 29;
576 		irq_start = S3C2410_IRQSUB(0);
577 		break;
578 	case 0x4a000040:
579 		pr_debug("irq: found intc2\n");
580 		intc->reg_pending = base + 0x40;
581 		intc->reg_mask = base + 0x48;
582 		intc->reg_intpnd = base + 0x50;
583 		irq_num = 8;
584 		irq_start = S3C2416_IRQ(0);
585 		break;
586 	case 0x560000a4:
587 		pr_debug("irq: found eintc\n");
588 		base = (void *)0xfd000000;
589 
590 		intc->reg_mask = base + 0xa4;
591 		intc->reg_pending = base + 0xa8;
592 		irq_num = 24;
593 		irq_start = S3C2410_IRQ(32);
594 		break;
595 	default:
596 		pr_err("irq: unsupported controller address\n");
597 		ret = -EINVAL;
598 		goto err;
599 	}
600 
601 	/* now that all the data is complete, init the irq-domain */
602 	s3c24xx_clear_intc(intc);
603 	intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
604 					     0, &s3c24xx_irq_ops,
605 					     intc);
606 	if (!intc->domain) {
607 		pr_err("irq: could not create irq-domain\n");
608 		ret = -EINVAL;
609 		goto err;
610 	}
611 
612 	set_handle_irq(s3c24xx_handle_irq);
613 
614 	return intc;
615 
616 err:
617 	kfree(intc);
618 	return ERR_PTR(ret);
619 }
620 
621 static struct s3c_irq_data init_eint[32] = {
622 	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
623 	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
624 	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
625 	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
626 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
627 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
628 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
629 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
630 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
631 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
632 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
633 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
634 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
635 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
636 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
637 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
638 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
639 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
640 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
641 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
642 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
643 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
644 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
645 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
646 };
647 
648 #ifdef CONFIG_CPU_S3C2410
649 static struct s3c_irq_data init_s3c2410base[32] = {
650 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
651 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
652 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
653 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
654 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
655 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
656 	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
657 	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
658 	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
659 	{ .type = S3C_IRQTYPE_EDGE, }, /* WDT */
660 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
661 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
662 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
663 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
664 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
665 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
666 	{ .type = S3C_IRQTYPE_EDGE, }, /* LCD */
667 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
668 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
669 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
670 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
671 	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI */
672 	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
673 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
674 	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
675 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
676 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */
677 	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
678 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
679 	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
680 	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
681 	{ .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
682 };
683 
684 static struct s3c_irq_data init_s3c2410subint[32] = {
685 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
686 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
687 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
688 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
689 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
690 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
691 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
692 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
693 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
694 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
695 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
696 };
697 
s3c2410_init_irq(void)698 void __init s3c2410_init_irq(void)
699 {
700 #ifdef CONFIG_FIQ
701 	init_FIQ(FIQ_START);
702 #endif
703 
704 	s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2410base[0], NULL,
705 					0x4a000000);
706 	if (IS_ERR(s3c_intc[0])) {
707 		pr_err("irq: could not create main interrupt controller\n");
708 		return;
709 	}
710 
711 	s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2410subint[0],
712 					s3c_intc[0], 0x4a000018);
713 	s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
714 }
715 #endif
716 
717 #ifdef CONFIG_CPU_S3C2412
718 static struct s3c_irq_data init_s3c2412base[32] = {
719 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT0 */
720 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT1 */
721 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT2 */
722 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT3 */
723 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
724 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
725 	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
726 	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
727 	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
728 	{ .type = S3C_IRQTYPE_EDGE, }, /* WDT */
729 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
730 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
731 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
732 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
733 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
734 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
735 	{ .type = S3C_IRQTYPE_EDGE, }, /* LCD */
736 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
737 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
738 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
739 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
740 	{ .type = S3C_IRQTYPE_LEVEL, }, /* SDI/CF */
741 	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
742 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
743 	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
744 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
745 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */
746 	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
747 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
748 	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
749 	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
750 	{ .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
751 };
752 
753 static struct s3c_irq_data init_s3c2412eint[32] = {
754 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 0 }, /* EINT0 */
755 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 1 }, /* EINT1 */
756 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 2 }, /* EINT2 */
757 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 3 }, /* EINT3 */
758 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
759 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
760 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
761 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
762 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
763 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
764 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
765 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
766 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
767 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
768 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
769 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
770 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
771 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
772 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
773 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
774 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
775 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
776 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
777 	{ .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
778 };
779 
780 static struct s3c_irq_data init_s3c2412subint[32] = {
781 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
782 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
783 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
784 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
785 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
786 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
787 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
788 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
789 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
790 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
791 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
792 	{ .type = S3C_IRQTYPE_NONE, },
793 	{ .type = S3C_IRQTYPE_NONE, },
794 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* SDI */
795 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */
796 };
797 
s3c2412_init_irq(void)798 void __init s3c2412_init_irq(void)
799 {
800 	pr_info("S3C2412: IRQ Support\n");
801 
802 #ifdef CONFIG_FIQ
803 	init_FIQ(FIQ_START);
804 #endif
805 
806 	s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2412base[0], NULL,
807 					0x4a000000);
808 	if (IS_ERR(s3c_intc[0])) {
809 		pr_err("irq: could not create main interrupt controller\n");
810 		return;
811 	}
812 
813 	s3c24xx_init_intc(NULL, &init_s3c2412eint[0], s3c_intc[0], 0x560000a4);
814 	s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2412subint[0],
815 					s3c_intc[0], 0x4a000018);
816 }
817 #endif
818 
819 #ifdef CONFIG_CPU_S3C2416
820 static struct s3c_irq_data init_s3c2416base[32] = {
821 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
822 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
823 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
824 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
825 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
826 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
827 	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
828 	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
829 	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
830 	{ .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
831 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
832 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
833 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
834 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
835 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
836 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
837 	{ .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
838 	{ .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
839 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
840 	{ .type = S3C_IRQTYPE_NONE, }, /* reserved */
841 	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
842 	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
843 	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
844 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
845 	{ .type = S3C_IRQTYPE_EDGE, }, /* NAND */
846 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
847 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */
848 	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
849 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
850 	{ .type = S3C_IRQTYPE_NONE, },
851 	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
852 	{ .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
853 };
854 
855 static struct s3c_irq_data init_s3c2416subint[32] = {
856 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
857 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
858 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
859 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
860 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
861 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
862 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
863 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
864 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
865 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
866 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
867 	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
868 	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
869 	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
870 	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
871 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
872 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
873 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
874 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
875 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
876 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
877 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
878 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
879 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
880 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
881 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
882 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
883 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
884 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
885 };
886 
887 static struct s3c_irq_data init_s3c2416_second[32] = {
888 	{ .type = S3C_IRQTYPE_EDGE }, /* 2D */
889 	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
890 	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
891 	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
892 	{ .type = S3C_IRQTYPE_EDGE }, /* PCM0 */
893 	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
894 	{ .type = S3C_IRQTYPE_EDGE }, /* I2S0 */
895 };
896 
s3c2416_init_irq(void)897 void __init s3c2416_init_irq(void)
898 {
899 	pr_info("S3C2416: IRQ Support\n");
900 
901 #ifdef CONFIG_FIQ
902 	init_FIQ(FIQ_START);
903 #endif
904 
905 	s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2416base[0], NULL,
906 					0x4a000000);
907 	if (IS_ERR(s3c_intc[0])) {
908 		pr_err("irq: could not create main interrupt controller\n");
909 		return;
910 	}
911 
912 	s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
913 	s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2416subint[0],
914 					s3c_intc[0], 0x4a000018);
915 
916 	s3c_intc[2] = s3c24xx_init_intc(NULL, &init_s3c2416_second[0],
917 					NULL, 0x4a000040);
918 }
919 
920 #endif
921 
922 #ifdef CONFIG_CPU_S3C2440
923 static struct s3c_irq_data init_s3c2440base[32] = {
924 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
925 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
926 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
927 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
928 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
929 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
930 	{ .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
931 	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
932 	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
933 	{ .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
934 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
935 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
936 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
937 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
938 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
939 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
940 	{ .type = S3C_IRQTYPE_EDGE, }, /* LCD */
941 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
942 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
943 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
944 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
945 	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI */
946 	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
947 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
948 	{ .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
949 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
950 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */
951 	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
952 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
953 	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
954 	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
955 	{ .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
956 };
957 
958 static struct s3c_irq_data init_s3c2440subint[32] = {
959 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
960 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
961 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
962 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
963 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
964 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
965 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
966 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
967 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
968 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
969 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
970 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
971 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
972 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
973 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
974 };
975 
s3c2440_init_irq(void)976 void __init s3c2440_init_irq(void)
977 {
978 	pr_info("S3C2440: IRQ Support\n");
979 
980 #ifdef CONFIG_FIQ
981 	init_FIQ(FIQ_START);
982 #endif
983 
984 	s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2440base[0], NULL,
985 					0x4a000000);
986 	if (IS_ERR(s3c_intc[0])) {
987 		pr_err("irq: could not create main interrupt controller\n");
988 		return;
989 	}
990 
991 	s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
992 	s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2440subint[0],
993 					s3c_intc[0], 0x4a000018);
994 }
995 #endif
996 
997 #ifdef CONFIG_CPU_S3C2442
998 static struct s3c_irq_data init_s3c2442base[32] = {
999 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
1000 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
1001 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
1002 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
1003 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
1004 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
1005 	{ .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
1006 	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
1007 	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
1008 	{ .type = S3C_IRQTYPE_EDGE, }, /* WDT */
1009 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
1010 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
1011 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
1012 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
1013 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
1014 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
1015 	{ .type = S3C_IRQTYPE_EDGE, }, /* LCD */
1016 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
1017 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
1018 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
1019 	{ .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
1020 	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI */
1021 	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
1022 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
1023 	{ .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
1024 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
1025 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */
1026 	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
1027 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
1028 	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
1029 	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
1030 	{ .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
1031 };
1032 
1033 static struct s3c_irq_data init_s3c2442subint[32] = {
1034 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
1035 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
1036 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
1037 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
1038 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
1039 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
1040 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
1041 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
1042 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
1043 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
1044 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
1045 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
1046 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
1047 };
1048 
s3c2442_init_irq(void)1049 void __init s3c2442_init_irq(void)
1050 {
1051 	pr_info("S3C2442: IRQ Support\n");
1052 
1053 #ifdef CONFIG_FIQ
1054 	init_FIQ(FIQ_START);
1055 #endif
1056 
1057 	s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2442base[0], NULL,
1058 					0x4a000000);
1059 	if (IS_ERR(s3c_intc[0])) {
1060 		pr_err("irq: could not create main interrupt controller\n");
1061 		return;
1062 	}
1063 
1064 	s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
1065 	s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2442subint[0],
1066 					s3c_intc[0], 0x4a000018);
1067 }
1068 #endif
1069 
1070 #ifdef CONFIG_CPU_S3C2443
1071 static struct s3c_irq_data init_s3c2443base[32] = {
1072 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
1073 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
1074 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
1075 	{ .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
1076 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
1077 	{ .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
1078 	{ .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
1079 	{ .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
1080 	{ .type = S3C_IRQTYPE_EDGE, }, /* TICK */
1081 	{ .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
1082 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
1083 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
1084 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
1085 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
1086 	{ .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
1087 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
1088 	{ .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
1089 	{ .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
1090 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
1091 	{ .type = S3C_IRQTYPE_EDGE, }, /* CFON */
1092 	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
1093 	{ .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
1094 	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
1095 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
1096 	{ .type = S3C_IRQTYPE_EDGE, }, /* NAND */
1097 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBD */
1098 	{ .type = S3C_IRQTYPE_EDGE, }, /* USBH */
1099 	{ .type = S3C_IRQTYPE_EDGE, }, /* IIC */
1100 	{ .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
1101 	{ .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
1102 	{ .type = S3C_IRQTYPE_EDGE, }, /* RTC */
1103 	{ .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
1104 };
1105 
1106 
1107 static struct s3c_irq_data init_s3c2443subint[32] = {
1108 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
1109 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
1110 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
1111 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
1112 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
1113 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
1114 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
1115 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
1116 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
1117 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
1118 	{ .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
1119 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
1120 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
1121 	{ .type = S3C_IRQTYPE_NONE }, /* reserved */
1122 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */
1123 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
1124 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
1125 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
1126 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
1127 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
1128 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
1129 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
1130 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
1131 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
1132 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
1133 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
1134 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
1135 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
1136 	{ .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
1137 };
1138 
s3c2443_init_irq(void)1139 void __init s3c2443_init_irq(void)
1140 {
1141 	pr_info("S3C2443: IRQ Support\n");
1142 
1143 #ifdef CONFIG_FIQ
1144 	init_FIQ(FIQ_START);
1145 #endif
1146 
1147 	s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL,
1148 					0x4a000000);
1149 	if (IS_ERR(s3c_intc[0])) {
1150 		pr_err("irq: could not create main interrupt controller\n");
1151 		return;
1152 	}
1153 
1154 	s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
1155 	s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2443subint[0],
1156 					s3c_intc[0], 0x4a000018);
1157 }
1158 #endif
1159 
1160 #ifdef CONFIG_OF
s3c24xx_irq_map_of(struct irq_domain * h,unsigned int virq,irq_hw_number_t hw)1161 static int s3c24xx_irq_map_of(struct irq_domain *h, unsigned int virq,
1162 							irq_hw_number_t hw)
1163 {
1164 	unsigned int ctrl_num = hw / 32;
1165 	unsigned int intc_hw = hw % 32;
1166 	struct s3c_irq_intc *intc = s3c_intc[ctrl_num];
1167 	struct s3c_irq_intc *parent_intc = intc->parent;
1168 	struct s3c_irq_data *irq_data = &intc->irqs[intc_hw];
1169 
1170 	/* attach controller pointer to irq_data */
1171 	irq_data->intc = intc;
1172 	irq_data->offset = intc_hw;
1173 
1174 	if (!parent_intc)
1175 		irq_set_chip_and_handler(virq, &s3c_irq_chip, handle_edge_irq);
1176 	else
1177 		irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
1178 					 handle_edge_irq);
1179 
1180 	irq_set_chip_data(virq, irq_data);
1181 
1182 	set_irq_flags(virq, IRQF_VALID);
1183 
1184 	return 0;
1185 }
1186 
1187 /* Translate our of irq notation
1188  * format: <ctrl_num ctrl_irq parent_irq type>
1189  */
s3c24xx_irq_xlate_of(struct irq_domain * d,struct device_node * n,const u32 * intspec,unsigned int intsize,irq_hw_number_t * out_hwirq,unsigned int * out_type)1190 static int s3c24xx_irq_xlate_of(struct irq_domain *d, struct device_node *n,
1191 			const u32 *intspec, unsigned int intsize,
1192 			irq_hw_number_t *out_hwirq, unsigned int *out_type)
1193 {
1194 	struct s3c_irq_intc *intc;
1195 	struct s3c_irq_intc *parent_intc;
1196 	struct s3c_irq_data *irq_data;
1197 	struct s3c_irq_data *parent_irq_data;
1198 	int irqno;
1199 
1200 	if (WARN_ON(intsize < 4))
1201 		return -EINVAL;
1202 
1203 	if (intspec[0] > 2 || !s3c_intc[intspec[0]]) {
1204 		pr_err("controller number %d invalid\n", intspec[0]);
1205 		return -EINVAL;
1206 	}
1207 	intc = s3c_intc[intspec[0]];
1208 
1209 	*out_hwirq = intspec[0] * 32 + intspec[2];
1210 	*out_type = intspec[3] & IRQ_TYPE_SENSE_MASK;
1211 
1212 	parent_intc = intc->parent;
1213 	if (parent_intc) {
1214 		irq_data = &intc->irqs[intspec[2]];
1215 		irq_data->parent_irq = intspec[1];
1216 		parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
1217 		parent_irq_data->sub_intc = intc;
1218 		parent_irq_data->sub_bits |= (1UL << intspec[2]);
1219 
1220 		/* parent_intc is always s3c_intc[0], so no offset */
1221 		irqno = irq_create_mapping(parent_intc->domain, intspec[1]);
1222 		if (irqno < 0) {
1223 			pr_err("irq: could not map parent interrupt\n");
1224 			return irqno;
1225 		}
1226 
1227 		irq_set_chained_handler(irqno, s3c_irq_demux);
1228 	}
1229 
1230 	return 0;
1231 }
1232 
1233 static struct irq_domain_ops s3c24xx_irq_ops_of = {
1234 	.map = s3c24xx_irq_map_of,
1235 	.xlate = s3c24xx_irq_xlate_of,
1236 };
1237 
1238 struct s3c24xx_irq_of_ctrl {
1239 	char			*name;
1240 	unsigned long		offset;
1241 	struct s3c_irq_intc	**handle;
1242 	struct s3c_irq_intc	**parent;
1243 	struct irq_domain_ops	*ops;
1244 };
1245 
s3c_init_intc_of(struct device_node * np,struct device_node * interrupt_parent,struct s3c24xx_irq_of_ctrl * s3c_ctrl,int num_ctrl)1246 static int __init s3c_init_intc_of(struct device_node *np,
1247 			struct device_node *interrupt_parent,
1248 			struct s3c24xx_irq_of_ctrl *s3c_ctrl, int num_ctrl)
1249 {
1250 	struct s3c_irq_intc *intc;
1251 	struct s3c24xx_irq_of_ctrl *ctrl;
1252 	struct irq_domain *domain;
1253 	void __iomem *reg_base;
1254 	int i;
1255 
1256 	reg_base = of_iomap(np, 0);
1257 	if (!reg_base) {
1258 		pr_err("irq-s3c24xx: could not map irq registers\n");
1259 		return -EINVAL;
1260 	}
1261 
1262 	domain = irq_domain_add_linear(np, num_ctrl * 32,
1263 						     &s3c24xx_irq_ops_of, NULL);
1264 	if (!domain) {
1265 		pr_err("irq: could not create irq-domain\n");
1266 		return -EINVAL;
1267 	}
1268 
1269 	for (i = 0; i < num_ctrl; i++) {
1270 		ctrl = &s3c_ctrl[i];
1271 
1272 		pr_debug("irq: found controller %s\n", ctrl->name);
1273 
1274 		intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
1275 		if (!intc)
1276 			return -ENOMEM;
1277 
1278 		intc->domain = domain;
1279 		intc->irqs = kzalloc(sizeof(struct s3c_irq_data) * 32,
1280 				     GFP_KERNEL);
1281 		if (!intc->irqs) {
1282 			kfree(intc);
1283 			return -ENOMEM;
1284 		}
1285 
1286 		if (ctrl->parent) {
1287 			intc->reg_pending = reg_base + ctrl->offset;
1288 			intc->reg_mask = reg_base + ctrl->offset + 0x4;
1289 
1290 			if (*(ctrl->parent)) {
1291 				intc->parent = *(ctrl->parent);
1292 			} else {
1293 				pr_warn("irq: parent of %s missing\n",
1294 					ctrl->name);
1295 				kfree(intc->irqs);
1296 				kfree(intc);
1297 				continue;
1298 			}
1299 		} else {
1300 			intc->reg_pending = reg_base + ctrl->offset;
1301 			intc->reg_mask = reg_base + ctrl->offset + 0x08;
1302 			intc->reg_intpnd = reg_base + ctrl->offset + 0x10;
1303 		}
1304 
1305 		s3c24xx_clear_intc(intc);
1306 		s3c_intc[i] = intc;
1307 	}
1308 
1309 	set_handle_irq(s3c24xx_handle_irq);
1310 
1311 	return 0;
1312 }
1313 
1314 static struct s3c24xx_irq_of_ctrl s3c2410_ctrl[] = {
1315 	{
1316 		.name = "intc",
1317 		.offset = 0,
1318 	}, {
1319 		.name = "subintc",
1320 		.offset = 0x18,
1321 		.parent = &s3c_intc[0],
1322 	}
1323 };
1324 
s3c2410_init_intc_of(struct device_node * np,struct device_node * interrupt_parent,struct s3c24xx_irq_of_ctrl * ctrl,int num_ctrl)1325 int __init s3c2410_init_intc_of(struct device_node *np,
1326 			struct device_node *interrupt_parent,
1327 			struct s3c24xx_irq_of_ctrl *ctrl, int num_ctrl)
1328 {
1329 	return s3c_init_intc_of(np, interrupt_parent,
1330 				s3c2410_ctrl, ARRAY_SIZE(s3c2410_ctrl));
1331 }
1332 IRQCHIP_DECLARE(s3c2410_irq, "samsung,s3c2410-irq", s3c2410_init_intc_of);
1333 
1334 static struct s3c24xx_irq_of_ctrl s3c2416_ctrl[] = {
1335 	{
1336 		.name = "intc",
1337 		.offset = 0,
1338 	}, {
1339 		.name = "subintc",
1340 		.offset = 0x18,
1341 		.parent = &s3c_intc[0],
1342 	}, {
1343 		.name = "intc2",
1344 		.offset = 0x40,
1345 	}
1346 };
1347 
s3c2416_init_intc_of(struct device_node * np,struct device_node * interrupt_parent,struct s3c24xx_irq_of_ctrl * ctrl,int num_ctrl)1348 int __init s3c2416_init_intc_of(struct device_node *np,
1349 			struct device_node *interrupt_parent,
1350 			struct s3c24xx_irq_of_ctrl *ctrl, int num_ctrl)
1351 {
1352 	return s3c_init_intc_of(np, interrupt_parent,
1353 				s3c2416_ctrl, ARRAY_SIZE(s3c2416_ctrl));
1354 }
1355 IRQCHIP_DECLARE(s3c2416_irq, "samsung,s3c2416-irq", s3c2416_init_intc_of);
1356 #endif
1357