• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * S3C24XX IRQ handling
4  *
5  * Copyright (c) 2003-2004 Simtec Electronics
6  *	Ben Dooks <ben@simtec.co.uk>
7  * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
8 */
9 
10 #include <linux/init.h>
11 #include <linux/slab.h>
12 #include <linux/module.h>
13 #include <linux/io.h>
14 #include <linux/err.h>
15 #include <linux/interrupt.h>
16 #include <linux/ioport.h>
17 #include <linux/device.h>
18 #include <linux/irqdomain.h>
19 #include <linux/irqchip.h>
20 #include <linux/irqchip/chained_irq.h>
21 #include <linux/of.h>
22 #include <linux/of_irq.h>
23 #include <linux/of_address.h>
24 #include <linux/spi/s3c24xx.h>
25 
26 #include <asm/exception.h>
27 #include <asm/mach/irq.h>
28 
29 #include <mach/irqs.h>
30 #include "regs-irq.h"
31 #include "regs-gpio.h"
32 
33 #include "cpu.h"
34 #include "regs-irqtype.h"
35 #include "pm.h"
36 #include "s3c24xx.h"
37 
38 #define S3C_IRQTYPE_NONE	0
39 #define S3C_IRQTYPE_EINT	1
40 #define S3C_IRQTYPE_EDGE	2
41 #define S3C_IRQTYPE_LEVEL	3
42 
43 struct s3c_irq_data {
44 	unsigned int type;
45 	unsigned long offset;
46 	unsigned long parent_irq;
47 
48 	/* data gets filled during init */
49 	struct s3c_irq_intc *intc;
50 	unsigned long sub_bits;
51 	struct s3c_irq_intc *sub_intc;
52 };
53 
54 /*
55  * Structure holding the controller data
56  * @reg_pending		register holding pending irqs
57  * @reg_intpnd		special register intpnd in main intc
58  * @reg_mask		mask register
59  * @domain		irq_domain of the controller
60  * @parent		parent controller for ext and sub irqs
61  * @irqs		irq-data, always s3c_irq_data[32]
62  */
63 struct s3c_irq_intc {
64 	void __iomem		*reg_pending;
65 	void __iomem		*reg_intpnd;
66 	void __iomem		*reg_mask;
67 	struct irq_domain	*domain;
68 	struct s3c_irq_intc	*parent;
69 	struct s3c_irq_data	*irqs;
70 };
71 
72 /*
73  * Array holding pointers to the global controller structs
74  * [0] ... main_intc
75  * [1] ... sub_intc
76  * [2] ... main_intc2 on s3c2416
77  */
78 static struct s3c_irq_intc *s3c_intc[3];
79 
s3c_irq_mask(struct irq_data * data)80 static void s3c_irq_mask(struct irq_data *data)
81 {
82 	struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
83 	struct s3c_irq_intc *intc = irq_data->intc;
84 	struct s3c_irq_intc *parent_intc = intc->parent;
85 	struct s3c_irq_data *parent_data;
86 	unsigned long mask;
87 	unsigned int irqno;
88 
89 	mask = readl_relaxed(intc->reg_mask);
90 	mask |= (1UL << irq_data->offset);
91 	writel_relaxed(mask, intc->reg_mask);
92 
93 	if (parent_intc) {
94 		parent_data = &parent_intc->irqs[irq_data->parent_irq];
95 
96 		/* check to see if we need to mask the parent IRQ
97 		 * The parent_irq is always in main_intc, so the hwirq
98 		 * for find_mapping does not need an offset in any case.
99 		 */
100 		if ((mask & parent_data->sub_bits) == parent_data->sub_bits) {
101 			irqno = irq_find_mapping(parent_intc->domain,
102 					 irq_data->parent_irq);
103 			s3c_irq_mask(irq_get_irq_data(irqno));
104 		}
105 	}
106 }
107 
s3c_irq_unmask(struct irq_data * data)108 static void s3c_irq_unmask(struct irq_data *data)
109 {
110 	struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
111 	struct s3c_irq_intc *intc = irq_data->intc;
112 	struct s3c_irq_intc *parent_intc = intc->parent;
113 	unsigned long mask;
114 	unsigned int irqno;
115 
116 	mask = readl_relaxed(intc->reg_mask);
117 	mask &= ~(1UL << irq_data->offset);
118 	writel_relaxed(mask, intc->reg_mask);
119 
120 	if (parent_intc) {
121 		irqno = irq_find_mapping(parent_intc->domain,
122 					 irq_data->parent_irq);
123 		s3c_irq_unmask(irq_get_irq_data(irqno));
124 	}
125 }
126 
s3c_irq_ack(struct irq_data * data)127 static inline void s3c_irq_ack(struct irq_data *data)
128 {
129 	struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
130 	struct s3c_irq_intc *intc = irq_data->intc;
131 	unsigned long bitval = 1UL << irq_data->offset;
132 
133 	writel_relaxed(bitval, intc->reg_pending);
134 	if (intc->reg_intpnd)
135 		writel_relaxed(bitval, intc->reg_intpnd);
136 }
137 
s3c_irq_type(struct irq_data * data,unsigned int type)138 static int s3c_irq_type(struct irq_data *data, unsigned int type)
139 {
140 	switch (type) {
141 	case IRQ_TYPE_NONE:
142 		break;
143 	case IRQ_TYPE_EDGE_RISING:
144 	case IRQ_TYPE_EDGE_FALLING:
145 	case IRQ_TYPE_EDGE_BOTH:
146 		irq_set_handler(data->irq, handle_edge_irq);
147 		break;
148 	case IRQ_TYPE_LEVEL_LOW:
149 	case IRQ_TYPE_LEVEL_HIGH:
150 		irq_set_handler(data->irq, handle_level_irq);
151 		break;
152 	default:
153 		pr_err("No such irq type %d\n", type);
154 		return -EINVAL;
155 	}
156 
157 	return 0;
158 }
159 
s3c_irqext_type_set(void __iomem * gpcon_reg,void __iomem * extint_reg,unsigned long gpcon_offset,unsigned long extint_offset,unsigned int type)160 static int s3c_irqext_type_set(void __iomem *gpcon_reg,
161 			       void __iomem *extint_reg,
162 			       unsigned long gpcon_offset,
163 			       unsigned long extint_offset,
164 			       unsigned int type)
165 {
166 	unsigned long newvalue = 0, value;
167 
168 	/* Set the GPIO to external interrupt mode */
169 	value = readl_relaxed(gpcon_reg);
170 	value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
171 	writel_relaxed(value, gpcon_reg);
172 
173 	/* Set the external interrupt to pointed trigger type */
174 	switch (type)
175 	{
176 		case IRQ_TYPE_NONE:
177 			pr_warn("No edge setting!\n");
178 			break;
179 
180 		case IRQ_TYPE_EDGE_RISING:
181 			newvalue = S3C2410_EXTINT_RISEEDGE;
182 			break;
183 
184 		case IRQ_TYPE_EDGE_FALLING:
185 			newvalue = S3C2410_EXTINT_FALLEDGE;
186 			break;
187 
188 		case IRQ_TYPE_EDGE_BOTH:
189 			newvalue = S3C2410_EXTINT_BOTHEDGE;
190 			break;
191 
192 		case IRQ_TYPE_LEVEL_LOW:
193 			newvalue = S3C2410_EXTINT_LOWLEV;
194 			break;
195 
196 		case IRQ_TYPE_LEVEL_HIGH:
197 			newvalue = S3C2410_EXTINT_HILEV;
198 			break;
199 
200 		default:
201 			pr_err("No such irq type %d\n", type);
202 			return -EINVAL;
203 	}
204 
205 	value = readl_relaxed(extint_reg);
206 	value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
207 	writel_relaxed(value, extint_reg);
208 
209 	return 0;
210 }
211 
s3c_irqext_type(struct irq_data * data,unsigned int type)212 static int s3c_irqext_type(struct irq_data *data, unsigned int type)
213 {
214 	void __iomem *extint_reg;
215 	void __iomem *gpcon_reg;
216 	unsigned long gpcon_offset, extint_offset;
217 
218 	if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
219 		gpcon_reg = S3C2410_GPFCON;
220 		extint_reg = S3C24XX_EXTINT0;
221 		gpcon_offset = (data->hwirq) * 2;
222 		extint_offset = (data->hwirq) * 4;
223 	} else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
224 		gpcon_reg = S3C2410_GPGCON;
225 		extint_reg = S3C24XX_EXTINT1;
226 		gpcon_offset = (data->hwirq - 8) * 2;
227 		extint_offset = (data->hwirq - 8) * 4;
228 	} else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
229 		gpcon_reg = S3C2410_GPGCON;
230 		extint_reg = S3C24XX_EXTINT2;
231 		gpcon_offset = (data->hwirq - 8) * 2;
232 		extint_offset = (data->hwirq - 16) * 4;
233 	} else {
234 		return -EINVAL;
235 	}
236 
237 	return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
238 				   extint_offset, type);
239 }
240 
s3c_irqext0_type(struct irq_data * data,unsigned int type)241 static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
242 {
243 	void __iomem *extint_reg;
244 	void __iomem *gpcon_reg;
245 	unsigned long gpcon_offset, extint_offset;
246 
247 	if (data->hwirq <= 3) {
248 		gpcon_reg = S3C2410_GPFCON;
249 		extint_reg = S3C24XX_EXTINT0;
250 		gpcon_offset = (data->hwirq) * 2;
251 		extint_offset = (data->hwirq) * 4;
252 	} else {
253 		return -EINVAL;
254 	}
255 
256 	return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
257 				   extint_offset, type);
258 }
259 
260 static struct irq_chip s3c_irq_chip = {
261 	.name		= "s3c",
262 	.irq_ack	= s3c_irq_ack,
263 	.irq_mask	= s3c_irq_mask,
264 	.irq_unmask	= s3c_irq_unmask,
265 	.irq_set_type	= s3c_irq_type,
266 	.irq_set_wake	= s3c_irq_wake
267 };
268 
269 static struct irq_chip s3c_irq_level_chip = {
270 	.name		= "s3c-level",
271 	.irq_mask	= s3c_irq_mask,
272 	.irq_unmask	= s3c_irq_unmask,
273 	.irq_ack	= s3c_irq_ack,
274 	.irq_set_type	= s3c_irq_type,
275 };
276 
277 static struct irq_chip s3c_irqext_chip = {
278 	.name		= "s3c-ext",
279 	.irq_mask	= s3c_irq_mask,
280 	.irq_unmask	= s3c_irq_unmask,
281 	.irq_ack	= s3c_irq_ack,
282 	.irq_set_type	= s3c_irqext_type,
283 	.irq_set_wake	= s3c_irqext_wake
284 };
285 
286 static struct irq_chip s3c_irq_eint0t4 = {
287 	.name		= "s3c-ext0",
288 	.irq_ack	= s3c_irq_ack,
289 	.irq_mask	= s3c_irq_mask,
290 	.irq_unmask	= s3c_irq_unmask,
291 	.irq_set_wake	= s3c_irq_wake,
292 	.irq_set_type	= s3c_irqext0_type,
293 };
294 
s3c_irq_demux(struct irq_desc * desc)295 static void s3c_irq_demux(struct irq_desc *desc)
296 {
297 	struct irq_chip *chip = irq_desc_get_chip(desc);
298 	struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc);
299 	struct s3c_irq_intc *intc = irq_data->intc;
300 	struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
301 	unsigned int n, offset;
302 	unsigned long src, msk;
303 
304 	/* we're using individual domains for the non-dt case
305 	 * and one big domain for the dt case where the subintc
306 	 * starts at hwirq number 32.
307 	 */
308 	offset = irq_domain_get_of_node(intc->domain) ? 32 : 0;
309 
310 	chained_irq_enter(chip, desc);
311 
312 	src = readl_relaxed(sub_intc->reg_pending);
313 	msk = readl_relaxed(sub_intc->reg_mask);
314 
315 	src &= ~msk;
316 	src &= irq_data->sub_bits;
317 
318 	while (src) {
319 		n = __ffs(src);
320 		src &= ~(1 << n);
321 		generic_handle_domain_irq(sub_intc->domain, offset + n);
322 	}
323 
324 	chained_irq_exit(chip, desc);
325 }
326 
s3c24xx_handle_intc(struct s3c_irq_intc * intc,struct pt_regs * regs,int intc_offset)327 static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
328 				      struct pt_regs *regs, int intc_offset)
329 {
330 	int pnd;
331 	int offset;
332 
333 	pnd = readl_relaxed(intc->reg_intpnd);
334 	if (!pnd)
335 		return false;
336 
337 	/* non-dt machines use individual domains */
338 	if (!irq_domain_get_of_node(intc->domain))
339 		intc_offset = 0;
340 
341 	/* We have a problem that the INTOFFSET register does not always
342 	 * show one interrupt. Occasionally we get two interrupts through
343 	 * the prioritiser, and this causes the INTOFFSET register to show
344 	 * what looks like the logical-or of the two interrupt numbers.
345 	 *
346 	 * Thanks to Klaus, Shannon, et al for helping to debug this problem
347 	 */
348 	offset = readl_relaxed(intc->reg_intpnd + 4);
349 
350 	/* Find the bit manually, when the offset is wrong.
351 	 * The pending register only ever contains the one bit of the next
352 	 * interrupt to handle.
353 	 */
354 	if (!(pnd & (1 << offset)))
355 		offset =  __ffs(pnd);
356 
357 	handle_domain_irq(intc->domain, intc_offset + offset, regs);
358 	return true;
359 }
360 
s3c24xx_handle_irq(struct pt_regs * regs)361 static asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs)
362 {
363 	do {
364 		/*
365 		 * For platform based machines, neither ERR nor NULL can happen here.
366 		 * The s3c24xx_handle_irq() will be set as IRQ handler iff this succeeds:
367 		 *
368 		 *    s3c_intc[0] = s3c24xx_init_intc()
369 		 *
370 		 * If this fails, the next calls to s3c24xx_init_intc() won't be executed.
371 		 *
372 		 * For DT machine, s3c_init_intc_of() could set the IRQ handler without
373 		 * setting s3c_intc[0] only if it was called with num_ctrl=0. There is no
374 		 * such code path, so again the s3c_intc[0] will have a valid pointer if
375 		 * set_handle_irq() is called.
376 		 *
377 		 * Therefore in s3c24xx_handle_irq(), the s3c_intc[0] is always something.
378 		 */
379 		if (s3c24xx_handle_intc(s3c_intc[0], regs, 0))
380 			continue;
381 
382 		if (!IS_ERR_OR_NULL(s3c_intc[2]))
383 			if (s3c24xx_handle_intc(s3c_intc[2], regs, 64))
384 				continue;
385 
386 		break;
387 	} while (1);
388 }
389 
390 #ifdef CONFIG_FIQ
391 /**
392  * s3c24xx_set_fiq - set the FIQ routing
393  * @irq: IRQ number to route to FIQ on processor.
394  * @ack_ptr: pointer to a location for storing the bit mask
395  * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
396  *
397  * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
398  * @on is true, the @irq is checked to see if it can be routed and the
399  * interrupt controller updated to route the IRQ. If @on is false, the FIQ
400  * routing is cleared, regardless of which @irq is specified.
401  *
402  * returns the mask value for the register.
403  */
s3c24xx_set_fiq(unsigned int irq,u32 * ack_ptr,bool on)404 int s3c24xx_set_fiq(unsigned int irq, u32 *ack_ptr, bool on)
405 {
406 	u32 intmod;
407 	unsigned offs;
408 
409 	if (on) {
410 		offs = irq - FIQ_START;
411 		if (offs > 31)
412 			return 0;
413 
414 		intmod = 1 << offs;
415 	} else {
416 		intmod = 0;
417 	}
418 
419 	if (ack_ptr)
420 		*ack_ptr = intmod;
421 	writel_relaxed(intmod, S3C2410_INTMOD);
422 
423 	return intmod;
424 }
425 
426 EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
427 #endif
428 
s3c24xx_irq_map(struct irq_domain * h,unsigned int virq,irq_hw_number_t hw)429 static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
430 							irq_hw_number_t hw)
431 {
432 	struct s3c_irq_intc *intc = h->host_data;
433 	struct s3c_irq_data *irq_data = &intc->irqs[hw];
434 	struct s3c_irq_intc *parent_intc;
435 	struct s3c_irq_data *parent_irq_data;
436 	unsigned int irqno;
437 
438 	/* attach controller pointer to irq_data */
439 	irq_data->intc = intc;
440 	irq_data->offset = hw;
441 
442 	parent_intc = intc->parent;
443 
444 	/* set handler and flags */
445 	switch (irq_data->type) {
446 	case S3C_IRQTYPE_NONE:
447 		return 0;
448 	case S3C_IRQTYPE_EINT:
449 		/* On the S3C2412, the EINT0to3 have a parent irq
450 		 * but need the s3c_irq_eint0t4 chip
451 		 */
452 		if (parent_intc && (!soc_is_s3c2412() || hw >= 4))
453 			irq_set_chip_and_handler(virq, &s3c_irqext_chip,
454 						 handle_edge_irq);
455 		else
456 			irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
457 						 handle_edge_irq);
458 		break;
459 	case S3C_IRQTYPE_EDGE:
460 		if (parent_intc || intc->reg_pending == S3C2416_SRCPND2)
461 			irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
462 						 handle_edge_irq);
463 		else
464 			irq_set_chip_and_handler(virq, &s3c_irq_chip,
465 						 handle_edge_irq);
466 		break;
467 	case S3C_IRQTYPE_LEVEL:
468 		if (parent_intc)
469 			irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
470 						 handle_level_irq);
471 		else
472 			irq_set_chip_and_handler(virq, &s3c_irq_chip,
473 						 handle_level_irq);
474 		break;
475 	default:
476 		pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
477 		return -EINVAL;
478 	}
479 
480 	irq_set_chip_data(virq, irq_data);
481 
482 	if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) {
483 		if (irq_data->parent_irq > 31) {
484 			pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
485 			       irq_data->parent_irq);
486 			return -EINVAL;
487 		}
488 
489 		parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
490 		parent_irq_data->sub_intc = intc;
491 		parent_irq_data->sub_bits |= (1UL << hw);
492 
493 		/* attach the demuxer to the parent irq */
494 		irqno = irq_find_mapping(parent_intc->domain,
495 					 irq_data->parent_irq);
496 		if (!irqno) {
497 			pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
498 			       irq_data->parent_irq);
499 			return -EINVAL;
500 		}
501 		irq_set_chained_handler(irqno, s3c_irq_demux);
502 	}
503 
504 	return 0;
505 }
506 
507 static const 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 = readl_relaxed(reg_source);
525 
526 		if (pend == 0 || pend == last)
527 			break;
528 
529 		writel_relaxed(pend, intc->reg_pending);
530 		if (intc->reg_intpnd)
531 			writel_relaxed(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 __maybe_unused 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 	return 0;
1183 }
1184 
1185 /* Translate our of irq notation
1186  * format: <ctrl_num ctrl_irq parent_irq type>
1187  */
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)1188 static int s3c24xx_irq_xlate_of(struct irq_domain *d, struct device_node *n,
1189 			const u32 *intspec, unsigned int intsize,
1190 			irq_hw_number_t *out_hwirq, unsigned int *out_type)
1191 {
1192 	struct s3c_irq_intc *intc;
1193 	struct s3c_irq_intc *parent_intc;
1194 	struct s3c_irq_data *irq_data;
1195 	struct s3c_irq_data *parent_irq_data;
1196 	int irqno;
1197 
1198 	if (WARN_ON(intsize < 4))
1199 		return -EINVAL;
1200 
1201 	if (intspec[0] > 2 || !s3c_intc[intspec[0]]) {
1202 		pr_err("controller number %d invalid\n", intspec[0]);
1203 		return -EINVAL;
1204 	}
1205 	intc = s3c_intc[intspec[0]];
1206 
1207 	*out_hwirq = intspec[0] * 32 + intspec[2];
1208 	*out_type = intspec[3] & IRQ_TYPE_SENSE_MASK;
1209 
1210 	parent_intc = intc->parent;
1211 	if (parent_intc) {
1212 		irq_data = &intc->irqs[intspec[2]];
1213 		irq_data->parent_irq = intspec[1];
1214 		parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
1215 		parent_irq_data->sub_intc = intc;
1216 		parent_irq_data->sub_bits |= (1UL << intspec[2]);
1217 
1218 		/* parent_intc is always s3c_intc[0], so no offset */
1219 		irqno = irq_create_mapping(parent_intc->domain, intspec[1]);
1220 		if (irqno < 0) {
1221 			pr_err("irq: could not map parent interrupt\n");
1222 			return irqno;
1223 		}
1224 
1225 		irq_set_chained_handler(irqno, s3c_irq_demux);
1226 	}
1227 
1228 	return 0;
1229 }
1230 
1231 static const struct irq_domain_ops s3c24xx_irq_ops_of = {
1232 	.map = s3c24xx_irq_map_of,
1233 	.xlate = s3c24xx_irq_xlate_of,
1234 };
1235 
1236 struct s3c24xx_irq_of_ctrl {
1237 	char			*name;
1238 	unsigned long		offset;
1239 	struct s3c_irq_intc	**handle;
1240 	struct s3c_irq_intc	**parent;
1241 	struct irq_domain_ops	*ops;
1242 };
1243 
s3c_init_intc_of(struct device_node * np,struct device_node * interrupt_parent,struct s3c24xx_irq_of_ctrl * s3c_ctrl,int num_ctrl)1244 static int __init s3c_init_intc_of(struct device_node *np,
1245 			struct device_node *interrupt_parent,
1246 			struct s3c24xx_irq_of_ctrl *s3c_ctrl, int num_ctrl)
1247 {
1248 	struct s3c_irq_intc *intc;
1249 	struct s3c24xx_irq_of_ctrl *ctrl;
1250 	struct irq_domain *domain;
1251 	void __iomem *reg_base;
1252 	int i;
1253 
1254 	reg_base = of_iomap(np, 0);
1255 	if (!reg_base) {
1256 		pr_err("irq-s3c24xx: could not map irq registers\n");
1257 		return -EINVAL;
1258 	}
1259 
1260 	domain = irq_domain_add_linear(np, num_ctrl * 32,
1261 						     &s3c24xx_irq_ops_of, NULL);
1262 	if (!domain) {
1263 		pr_err("irq: could not create irq-domain\n");
1264 		return -EINVAL;
1265 	}
1266 
1267 	for (i = 0; i < num_ctrl; i++) {
1268 		ctrl = &s3c_ctrl[i];
1269 
1270 		pr_debug("irq: found controller %s\n", ctrl->name);
1271 
1272 		intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
1273 		if (!intc)
1274 			return -ENOMEM;
1275 
1276 		intc->domain = domain;
1277 		intc->irqs = kcalloc(32, sizeof(struct s3c_irq_data),
1278 				     GFP_KERNEL);
1279 		if (!intc->irqs) {
1280 			kfree(intc);
1281 			return -ENOMEM;
1282 		}
1283 
1284 		if (ctrl->parent) {
1285 			intc->reg_pending = reg_base + ctrl->offset;
1286 			intc->reg_mask = reg_base + ctrl->offset + 0x4;
1287 
1288 			if (*(ctrl->parent)) {
1289 				intc->parent = *(ctrl->parent);
1290 			} else {
1291 				pr_warn("irq: parent of %s missing\n",
1292 					ctrl->name);
1293 				kfree(intc->irqs);
1294 				kfree(intc);
1295 				continue;
1296 			}
1297 		} else {
1298 			intc->reg_pending = reg_base + ctrl->offset;
1299 			intc->reg_mask = reg_base + ctrl->offset + 0x08;
1300 			intc->reg_intpnd = reg_base + ctrl->offset + 0x10;
1301 		}
1302 
1303 		s3c24xx_clear_intc(intc);
1304 		s3c_intc[i] = intc;
1305 	}
1306 
1307 	set_handle_irq(s3c24xx_handle_irq);
1308 
1309 	return 0;
1310 }
1311 
1312 static struct s3c24xx_irq_of_ctrl s3c2410_ctrl[] = {
1313 	{
1314 		.name = "intc",
1315 		.offset = 0,
1316 	}, {
1317 		.name = "subintc",
1318 		.offset = 0x18,
1319 		.parent = &s3c_intc[0],
1320 	}
1321 };
1322 
s3c2410_init_intc_of(struct device_node * np,struct device_node * interrupt_parent)1323 static int __init s3c2410_init_intc_of(struct device_node *np,
1324 			struct device_node *interrupt_parent)
1325 {
1326 	return s3c_init_intc_of(np, interrupt_parent,
1327 				s3c2410_ctrl, ARRAY_SIZE(s3c2410_ctrl));
1328 }
1329 IRQCHIP_DECLARE(s3c2410_irq, "samsung,s3c2410-irq", s3c2410_init_intc_of);
1330 
1331 static struct s3c24xx_irq_of_ctrl s3c2416_ctrl[] = {
1332 	{
1333 		.name = "intc",
1334 		.offset = 0,
1335 	}, {
1336 		.name = "subintc",
1337 		.offset = 0x18,
1338 		.parent = &s3c_intc[0],
1339 	}, {
1340 		.name = "intc2",
1341 		.offset = 0x40,
1342 	}
1343 };
1344 
s3c2416_init_intc_of(struct device_node * np,struct device_node * interrupt_parent)1345 static int __init s3c2416_init_intc_of(struct device_node *np,
1346 			struct device_node *interrupt_parent)
1347 {
1348 	return s3c_init_intc_of(np, interrupt_parent,
1349 				s3c2416_ctrl, ARRAY_SIZE(s3c2416_ctrl));
1350 }
1351 IRQCHIP_DECLARE(s3c2416_irq, "samsung,s3c2416-irq", s3c2416_init_intc_of);
1352 #endif
1353