Commit 8a407835bef6d47dcef9594d8c85900f994fbedf

Authored by Heiko Stuebner
Committed by Kukjin Kim
1 parent 17453dd2e7

ARM: S3C24XX: move irq driver to drivers/irqchip

This move is necessary to make use of the irqchip infrastructure
for the following devicetree support for s3c24xx architectures.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>

Showing 4 changed files with 1109 additions and 1108 deletions Side-by-side Diff

arch/arm/mach-s3c24xx/Makefile
... ... @@ -14,7 +14,7 @@
14 14  
15 15 # core
16 16  
17   -obj-y += common.o irq.o
  17 +obj-y += common.o
18 18  
19 19 obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
20 20 obj-$(CONFIG_S3C2410_CPUFREQ) += cpufreq-s3c2410.o
arch/arm/mach-s3c24xx/irq.c
Changes suppressed. Click to show
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   -
29   -#include <asm/exception.h>
30   -#include <asm/mach/irq.h>
31   -
32   -#include <mach/regs-irq.h>
33   -#include <mach/regs-gpio.h>
34   -
35   -#include <plat/cpu.h>
36   -#include <plat/regs-irqtype.h>
37   -#include <plat/pm.h>
38   -
39   -#define S3C_IRQTYPE_NONE 0
40   -#define S3C_IRQTYPE_EINT 1
41   -#define S3C_IRQTYPE_EDGE 2
42   -#define S3C_IRQTYPE_LEVEL 3
43   -
44   -struct s3c_irq_data {
45   - unsigned int type;
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   - * Sructure 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   -static void s3c_irq_mask(struct irq_data *data)
73   -{
74   - struct s3c_irq_intc *intc = data->domain->host_data;
75   - struct s3c_irq_intc *parent_intc = intc->parent;
76   - struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
77   - struct s3c_irq_data *parent_data;
78   - unsigned long mask;
79   - unsigned int irqno;
80   -
81   - mask = __raw_readl(intc->reg_mask);
82   - mask |= (1UL << data->hwirq);
83   - __raw_writel(mask, intc->reg_mask);
84   -
85   - if (parent_intc) {
86   - parent_data = &parent_intc->irqs[irq_data->parent_irq];
87   -
88   - /* check to see if we need to mask the parent IRQ */
89   - if ((mask & parent_data->sub_bits) == parent_data->sub_bits) {
90   - irqno = irq_find_mapping(parent_intc->domain,
91   - irq_data->parent_irq);
92   - s3c_irq_mask(irq_get_irq_data(irqno));
93   - }
94   - }
95   -}
96   -
97   -static void s3c_irq_unmask(struct irq_data *data)
98   -{
99   - struct s3c_irq_intc *intc = data->domain->host_data;
100   - struct s3c_irq_intc *parent_intc = intc->parent;
101   - struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
102   - unsigned long mask;
103   - unsigned int irqno;
104   -
105   - mask = __raw_readl(intc->reg_mask);
106   - mask &= ~(1UL << data->hwirq);
107   - __raw_writel(mask, intc->reg_mask);
108   -
109   - if (parent_intc) {
110   - irqno = irq_find_mapping(parent_intc->domain,
111   - irq_data->parent_irq);
112   - s3c_irq_unmask(irq_get_irq_data(irqno));
113   - }
114   -}
115   -
116   -static inline void s3c_irq_ack(struct irq_data *data)
117   -{
118   - struct s3c_irq_intc *intc = data->domain->host_data;
119   - unsigned long bitval = 1UL << data->hwirq;
120   -
121   - __raw_writel(bitval, intc->reg_pending);
122   - if (intc->reg_intpnd)
123   - __raw_writel(bitval, intc->reg_intpnd);
124   -}
125   -
126   -static int s3c_irqext_type_set(void __iomem *gpcon_reg,
127   - void __iomem *extint_reg,
128   - unsigned long gpcon_offset,
129   - unsigned long extint_offset,
130   - unsigned int type)
131   -{
132   - unsigned long newvalue = 0, value;
133   -
134   - /* Set the GPIO to external interrupt mode */
135   - value = __raw_readl(gpcon_reg);
136   - value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
137   - __raw_writel(value, gpcon_reg);
138   -
139   - /* Set the external interrupt to pointed trigger type */
140   - switch (type)
141   - {
142   - case IRQ_TYPE_NONE:
143   - pr_warn("No edge setting!\n");
144   - break;
145   -
146   - case IRQ_TYPE_EDGE_RISING:
147   - newvalue = S3C2410_EXTINT_RISEEDGE;
148   - break;
149   -
150   - case IRQ_TYPE_EDGE_FALLING:
151   - newvalue = S3C2410_EXTINT_FALLEDGE;
152   - break;
153   -
154   - case IRQ_TYPE_EDGE_BOTH:
155   - newvalue = S3C2410_EXTINT_BOTHEDGE;
156   - break;
157   -
158   - case IRQ_TYPE_LEVEL_LOW:
159   - newvalue = S3C2410_EXTINT_LOWLEV;
160   - break;
161   -
162   - case IRQ_TYPE_LEVEL_HIGH:
163   - newvalue = S3C2410_EXTINT_HILEV;
164   - break;
165   -
166   - default:
167   - pr_err("No such irq type %d", type);
168   - return -EINVAL;
169   - }
170   -
171   - value = __raw_readl(extint_reg);
172   - value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
173   - __raw_writel(value, extint_reg);
174   -
175   - return 0;
176   -}
177   -
178   -static int s3c_irqext_type(struct irq_data *data, unsigned int type)
179   -{
180   - void __iomem *extint_reg;
181   - void __iomem *gpcon_reg;
182   - unsigned long gpcon_offset, extint_offset;
183   -
184   - if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
185   - gpcon_reg = S3C2410_GPFCON;
186   - extint_reg = S3C24XX_EXTINT0;
187   - gpcon_offset = (data->hwirq) * 2;
188   - extint_offset = (data->hwirq) * 4;
189   - } else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
190   - gpcon_reg = S3C2410_GPGCON;
191   - extint_reg = S3C24XX_EXTINT1;
192   - gpcon_offset = (data->hwirq - 8) * 2;
193   - extint_offset = (data->hwirq - 8) * 4;
194   - } else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
195   - gpcon_reg = S3C2410_GPGCON;
196   - extint_reg = S3C24XX_EXTINT2;
197   - gpcon_offset = (data->hwirq - 8) * 2;
198   - extint_offset = (data->hwirq - 16) * 4;
199   - } else {
200   - return -EINVAL;
201   - }
202   -
203   - return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
204   - extint_offset, type);
205   -}
206   -
207   -static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
208   -{
209   - void __iomem *extint_reg;
210   - void __iomem *gpcon_reg;
211   - unsigned long gpcon_offset, extint_offset;
212   -
213   - if ((data->hwirq >= 0) && (data->hwirq <= 3)) {
214   - gpcon_reg = S3C2410_GPFCON;
215   - extint_reg = S3C24XX_EXTINT0;
216   - gpcon_offset = (data->hwirq) * 2;
217   - extint_offset = (data->hwirq) * 4;
218   - } else {
219   - return -EINVAL;
220   - }
221   -
222   - return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
223   - extint_offset, type);
224   -}
225   -
226   -static struct irq_chip s3c_irq_chip = {
227   - .name = "s3c",
228   - .irq_ack = s3c_irq_ack,
229   - .irq_mask = s3c_irq_mask,
230   - .irq_unmask = s3c_irq_unmask,
231   - .irq_set_wake = s3c_irq_wake
232   -};
233   -
234   -static struct irq_chip s3c_irq_level_chip = {
235   - .name = "s3c-level",
236   - .irq_mask = s3c_irq_mask,
237   - .irq_unmask = s3c_irq_unmask,
238   - .irq_ack = s3c_irq_ack,
239   -};
240   -
241   -static struct irq_chip s3c_irqext_chip = {
242   - .name = "s3c-ext",
243   - .irq_mask = s3c_irq_mask,
244   - .irq_unmask = s3c_irq_unmask,
245   - .irq_ack = s3c_irq_ack,
246   - .irq_set_type = s3c_irqext_type,
247   - .irq_set_wake = s3c_irqext_wake
248   -};
249   -
250   -static struct irq_chip s3c_irq_eint0t4 = {
251   - .name = "s3c-ext0",
252   - .irq_ack = s3c_irq_ack,
253   - .irq_mask = s3c_irq_mask,
254   - .irq_unmask = s3c_irq_unmask,
255   - .irq_set_wake = s3c_irq_wake,
256   - .irq_set_type = s3c_irqext0_type,
257   -};
258   -
259   -static void s3c_irq_demux(unsigned int irq, struct irq_desc *desc)
260   -{
261   - struct irq_chip *chip = irq_desc_get_chip(desc);
262   - struct s3c_irq_intc *intc = desc->irq_data.domain->host_data;
263   - struct s3c_irq_data *irq_data = &intc->irqs[desc->irq_data.hwirq];
264   - struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
265   - unsigned long src;
266   - unsigned long msk;
267   - unsigned int n;
268   -
269   - chained_irq_enter(chip, desc);
270   -
271   - src = __raw_readl(sub_intc->reg_pending);
272   - msk = __raw_readl(sub_intc->reg_mask);
273   -
274   - src &= ~msk;
275   - src &= irq_data->sub_bits;
276   -
277   - while (src) {
278   - n = __ffs(src);
279   - src &= ~(1 << n);
280   - generic_handle_irq(irq_find_mapping(sub_intc->domain, n));
281   - }
282   -
283   - chained_irq_exit(chip, desc);
284   -}
285   -
286   -static struct s3c_irq_intc *main_intc;
287   -static struct s3c_irq_intc *main_intc2;
288   -
289   -static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
290   - struct pt_regs *regs)
291   -{
292   - int pnd;
293   - int offset;
294   - int irq;
295   -
296   - pnd = __raw_readl(intc->reg_intpnd);
297   - if (!pnd)
298   - return false;
299   -
300   - /* We have a problem that the INTOFFSET register does not always
301   - * show one interrupt. Occasionally we get two interrupts through
302   - * the prioritiser, and this causes the INTOFFSET register to show
303   - * what looks like the logical-or of the two interrupt numbers.
304   - *
305   - * Thanks to Klaus, Shannon, et al for helping to debug this problem
306   - */
307   - offset = __raw_readl(intc->reg_intpnd + 4);
308   -
309   - /* Find the bit manually, when the offset is wrong.
310   - * The pending register only ever contains the one bit of the next
311   - * interrupt to handle.
312   - */
313   - if (!(pnd & (1 << offset)))
314   - offset = __ffs(pnd);
315   -
316   - irq = irq_find_mapping(intc->domain, offset);
317   - handle_IRQ(irq, regs);
318   - return true;
319   -}
320   -
321   -asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs)
322   -{
323   - do {
324   - if (likely(main_intc))
325   - if (s3c24xx_handle_intc(main_intc, regs))
326   - continue;
327   -
328   - if (main_intc2)
329   - if (s3c24xx_handle_intc(main_intc2, regs))
330   - continue;
331   -
332   - break;
333   - } while (1);
334   -}
335   -
336   -#ifdef CONFIG_FIQ
337   -/**
338   - * s3c24xx_set_fiq - set the FIQ routing
339   - * @irq: IRQ number to route to FIQ on processor.
340   - * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
341   - *
342   - * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
343   - * @on is true, the @irq is checked to see if it can be routed and the
344   - * interrupt controller updated to route the IRQ. If @on is false, the FIQ
345   - * routing is cleared, regardless of which @irq is specified.
346   - */
347   -int s3c24xx_set_fiq(unsigned int irq, bool on)
348   -{
349   - u32 intmod;
350   - unsigned offs;
351   -
352   - if (on) {
353   - offs = irq - FIQ_START;
354   - if (offs > 31)
355   - return -EINVAL;
356   -
357   - intmod = 1 << offs;
358   - } else {
359   - intmod = 0;
360   - }
361   -
362   - __raw_writel(intmod, S3C2410_INTMOD);
363   - return 0;
364   -}
365   -
366   -EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
367   -#endif
368   -
369   -static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
370   - irq_hw_number_t hw)
371   -{
372   - struct s3c_irq_intc *intc = h->host_data;
373   - struct s3c_irq_data *irq_data = &intc->irqs[hw];
374   - struct s3c_irq_intc *parent_intc;
375   - struct s3c_irq_data *parent_irq_data;
376   - unsigned int irqno;
377   -
378   - /* attach controller pointer to irq_data */
379   - irq_data->intc = intc;
380   -
381   - parent_intc = intc->parent;
382   -
383   - /* set handler and flags */
384   - switch (irq_data->type) {
385   - case S3C_IRQTYPE_NONE:
386   - return 0;
387   - case S3C_IRQTYPE_EINT:
388   - /* On the S3C2412, the EINT0to3 have a parent irq
389   - * but need the s3c_irq_eint0t4 chip
390   - */
391   - if (parent_intc && (!soc_is_s3c2412() || hw >= 4))
392   - irq_set_chip_and_handler(virq, &s3c_irqext_chip,
393   - handle_edge_irq);
394   - else
395   - irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
396   - handle_edge_irq);
397   - break;
398   - case S3C_IRQTYPE_EDGE:
399   - if (parent_intc || intc->reg_pending == S3C2416_SRCPND2)
400   - irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
401   - handle_edge_irq);
402   - else
403   - irq_set_chip_and_handler(virq, &s3c_irq_chip,
404   - handle_edge_irq);
405   - break;
406   - case S3C_IRQTYPE_LEVEL:
407   - if (parent_intc)
408   - irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
409   - handle_level_irq);
410   - else
411   - irq_set_chip_and_handler(virq, &s3c_irq_chip,
412   - handle_level_irq);
413   - break;
414   - default:
415   - pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
416   - return -EINVAL;
417   - }
418   - set_irq_flags(virq, IRQF_VALID);
419   -
420   - if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) {
421   - if (irq_data->parent_irq > 31) {
422   - pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
423   - irq_data->parent_irq);
424   - goto err;
425   - }
426   -
427   - parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
428   - parent_irq_data->sub_intc = intc;
429   - parent_irq_data->sub_bits |= (1UL << hw);
430   -
431   - /* attach the demuxer to the parent irq */
432   - irqno = irq_find_mapping(parent_intc->domain,
433   - irq_data->parent_irq);
434   - if (!irqno) {
435   - pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
436   - irq_data->parent_irq);
437   - goto err;
438   - }
439   - irq_set_chained_handler(irqno, s3c_irq_demux);
440   - }
441   -
442   - return 0;
443   -
444   -err:
445   - set_irq_flags(virq, 0);
446   -
447   - /* the only error can result from bad mapping data*/
448   - return -EINVAL;
449   -}
450   -
451   -static struct irq_domain_ops s3c24xx_irq_ops = {
452   - .map = s3c24xx_irq_map,
453   - .xlate = irq_domain_xlate_twocell,
454   -};
455   -
456   -static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
457   -{
458   - void __iomem *reg_source;
459   - unsigned long pend;
460   - unsigned long last;
461   - int i;
462   -
463   - /* if intpnd is set, read the next pending irq from there */
464   - reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending;
465   -
466   - last = 0;
467   - for (i = 0; i < 4; i++) {
468   - pend = __raw_readl(reg_source);
469   -
470   - if (pend == 0 || pend == last)
471   - break;
472   -
473   - __raw_writel(pend, intc->reg_pending);
474   - if (intc->reg_intpnd)
475   - __raw_writel(pend, intc->reg_intpnd);
476   -
477   - pr_info("irq: clearing pending status %08x\n", (int)pend);
478   - last = pend;
479   - }
480   -}
481   -
482   -static struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np,
483   - struct s3c_irq_data *irq_data,
484   - struct s3c_irq_intc *parent,
485   - unsigned long address)
486   -{
487   - struct s3c_irq_intc *intc;
488   - void __iomem *base = (void *)0xf6000000; /* static mapping */
489   - int irq_num;
490   - int irq_start;
491   - int ret;
492   -
493   - intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
494   - if (!intc)
495   - return ERR_PTR(-ENOMEM);
496   -
497   - intc->irqs = irq_data;
498   -
499   - if (parent)
500   - intc->parent = parent;
501   -
502   - /* select the correct data for the controller.
503   - * Need to hard code the irq num start and offset
504   - * to preserve the static mapping for now
505   - */
506   - switch (address) {
507   - case 0x4a000000:
508   - pr_debug("irq: found main intc\n");
509   - intc->reg_pending = base;
510   - intc->reg_mask = base + 0x08;
511   - intc->reg_intpnd = base + 0x10;
512   - irq_num = 32;
513   - irq_start = S3C2410_IRQ(0);
514   - break;
515   - case 0x4a000018:
516   - pr_debug("irq: found subintc\n");
517   - intc->reg_pending = base + 0x18;
518   - intc->reg_mask = base + 0x1c;
519   - irq_num = 29;
520   - irq_start = S3C2410_IRQSUB(0);
521   - break;
522   - case 0x4a000040:
523   - pr_debug("irq: found intc2\n");
524   - intc->reg_pending = base + 0x40;
525   - intc->reg_mask = base + 0x48;
526   - intc->reg_intpnd = base + 0x50;
527   - irq_num = 8;
528   - irq_start = S3C2416_IRQ(0);
529   - break;
530   - case 0x560000a4:
531   - pr_debug("irq: found eintc\n");
532   - base = (void *)0xfd000000;
533   -
534   - intc->reg_mask = base + 0xa4;
535   - intc->reg_pending = base + 0x08;
536   - irq_num = 24;
537   - irq_start = S3C2410_IRQ(32);
538   - break;
539   - default:
540   - pr_err("irq: unsupported controller address\n");
541   - ret = -EINVAL;
542   - goto err;
543   - }
544   -
545   - /* now that all the data is complete, init the irq-domain */
546   - s3c24xx_clear_intc(intc);
547   - intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
548   - 0, &s3c24xx_irq_ops,
549   - intc);
550   - if (!intc->domain) {
551   - pr_err("irq: could not create irq-domain\n");
552   - ret = -EINVAL;
553   - goto err;
554   - }
555   -
556   - if (address == 0x4a000000)
557   - main_intc = intc;
558   - else if (address == 0x4a000040)
559   - main_intc2 = intc;
560   -
561   - set_handle_irq(s3c24xx_handle_irq);
562   -
563   - return intc;
564   -
565   -err:
566   - kfree(intc);
567   - return ERR_PTR(ret);
568   -}
569   -
570   -static struct s3c_irq_data init_eint[32] = {
571   - { .type = S3C_IRQTYPE_NONE, }, /* reserved */
572   - { .type = S3C_IRQTYPE_NONE, }, /* reserved */
573   - { .type = S3C_IRQTYPE_NONE, }, /* reserved */
574   - { .type = S3C_IRQTYPE_NONE, }, /* reserved */
575   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
576   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
577   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
578   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
579   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
580   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
581   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
582   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
583   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
584   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
585   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
586   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
587   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
588   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
589   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
590   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
591   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
592   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
593   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
594   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
595   -};
596   -
597   -#ifdef CONFIG_CPU_S3C2410
598   -static struct s3c_irq_data init_s3c2410base[32] = {
599   - { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
600   - { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
601   - { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
602   - { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
603   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
604   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
605   - { .type = S3C_IRQTYPE_NONE, }, /* reserved */
606   - { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
607   - { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
608   - { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
609   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
610   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
611   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
612   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
613   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
614   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
615   - { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
616   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
617   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
618   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
619   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
620   - { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
621   - { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
622   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
623   - { .type = S3C_IRQTYPE_NONE, }, /* reserved */
624   - { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
625   - { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
626   - { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
627   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
628   - { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
629   - { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
630   - { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
631   -};
632   -
633   -static struct s3c_irq_data init_s3c2410subint[32] = {
634   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
635   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
636   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
637   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
638   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
639   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
640   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
641   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
642   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
643   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
644   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
645   -};
646   -
647   -void __init s3c2410_init_irq(void)
648   -{
649   - struct s3c_irq_intc *main_intc;
650   -
651   -#ifdef CONFIG_FIQ
652   - init_FIQ(FIQ_START);
653   -#endif
654   -
655   - main_intc = s3c24xx_init_intc(NULL, &init_s3c2410base[0], NULL, 0x4a000000);
656   - if (IS_ERR(main_intc)) {
657   - pr_err("irq: could not create main interrupt controller\n");
658   - return;
659   - }
660   -
661   - s3c24xx_init_intc(NULL, &init_s3c2410subint[0], main_intc, 0x4a000018);
662   - s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
663   -}
664   -#endif
665   -
666   -#ifdef CONFIG_CPU_S3C2412
667   -static struct s3c_irq_data init_s3c2412base[32] = {
668   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT0 */
669   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT1 */
670   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT2 */
671   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT3 */
672   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
673   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
674   - { .type = S3C_IRQTYPE_NONE, }, /* reserved */
675   - { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
676   - { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
677   - { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
678   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
679   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
680   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
681   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
682   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
683   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
684   - { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
685   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
686   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
687   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
688   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
689   - { .type = S3C_IRQTYPE_LEVEL, }, /* SDI/CF */
690   - { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
691   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
692   - { .type = S3C_IRQTYPE_NONE, }, /* reserved */
693   - { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
694   - { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
695   - { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
696   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
697   - { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
698   - { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
699   - { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
700   -};
701   -
702   -static struct s3c_irq_data init_s3c2412eint[32] = {
703   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 0 }, /* EINT0 */
704   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 1 }, /* EINT1 */
705   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 2 }, /* EINT2 */
706   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 3 }, /* EINT3 */
707   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
708   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
709   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
710   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
711   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
712   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
713   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
714   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
715   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
716   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
717   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
718   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
719   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
720   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
721   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
722   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
723   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
724   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
725   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
726   - { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
727   -};
728   -
729   -static struct s3c_irq_data init_s3c2412subint[32] = {
730   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
731   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
732   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
733   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
734   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
735   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
736   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
737   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
738   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
739   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
740   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
741   - { .type = S3C_IRQTYPE_NONE, },
742   - { .type = S3C_IRQTYPE_NONE, },
743   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* SDI */
744   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */
745   -};
746   -
747   -void s3c2412_init_irq(void)
748   -{
749   - struct s3c_irq_intc *main_intc;
750   -
751   - pr_info("S3C2412: IRQ Support\n");
752   -
753   -#ifdef CONFIG_FIQ
754   - init_FIQ(FIQ_START);
755   -#endif
756   -
757   - main_intc = s3c24xx_init_intc(NULL, &init_s3c2412base[0], NULL, 0x4a000000);
758   - if (IS_ERR(main_intc)) {
759   - pr_err("irq: could not create main interrupt controller\n");
760   - return;
761   - }
762   -
763   - s3c24xx_init_intc(NULL, &init_s3c2412eint[0], main_intc, 0x560000a4);
764   - s3c24xx_init_intc(NULL, &init_s3c2412subint[0], main_intc, 0x4a000018);
765   -}
766   -#endif
767   -
768   -#ifdef CONFIG_CPU_S3C2416
769   -static struct s3c_irq_data init_s3c2416base[32] = {
770   - { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
771   - { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
772   - { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
773   - { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
774   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
775   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
776   - { .type = S3C_IRQTYPE_NONE, }, /* reserved */
777   - { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
778   - { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
779   - { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
780   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
781   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
782   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
783   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
784   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
785   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
786   - { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
787   - { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
788   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
789   - { .type = S3C_IRQTYPE_NONE, }, /* reserved */
790   - { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
791   - { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
792   - { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
793   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
794   - { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
795   - { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
796   - { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
797   - { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
798   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
799   - { .type = S3C_IRQTYPE_NONE, },
800   - { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
801   - { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
802   -};
803   -
804   -static struct s3c_irq_data init_s3c2416subint[32] = {
805   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
806   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
807   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
808   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
809   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
810   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
811   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
812   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
813   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
814   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
815   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
816   - { .type = S3C_IRQTYPE_NONE }, /* reserved */
817   - { .type = S3C_IRQTYPE_NONE }, /* reserved */
818   - { .type = S3C_IRQTYPE_NONE }, /* reserved */
819   - { .type = S3C_IRQTYPE_NONE }, /* reserved */
820   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
821   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
822   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
823   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
824   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
825   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
826   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
827   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
828   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
829   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
830   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
831   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
832   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
833   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
834   -};
835   -
836   -static struct s3c_irq_data init_s3c2416_second[32] = {
837   - { .type = S3C_IRQTYPE_EDGE }, /* 2D */
838   - { .type = S3C_IRQTYPE_EDGE }, /* IIC1 */
839   - { .type = S3C_IRQTYPE_NONE }, /* reserved */
840   - { .type = S3C_IRQTYPE_NONE }, /* reserved */
841   - { .type = S3C_IRQTYPE_EDGE }, /* PCM0 */
842   - { .type = S3C_IRQTYPE_EDGE }, /* PCM1 */
843   - { .type = S3C_IRQTYPE_EDGE }, /* I2S0 */
844   - { .type = S3C_IRQTYPE_EDGE }, /* I2S1 */
845   -};
846   -
847   -void __init s3c2416_init_irq(void)
848   -{
849   - struct s3c_irq_intc *main_intc;
850   -
851   - pr_info("S3C2416: IRQ Support\n");
852   -
853   -#ifdef CONFIG_FIQ
854   - init_FIQ(FIQ_START);
855   -#endif
856   -
857   - main_intc = s3c24xx_init_intc(NULL, &init_s3c2416base[0], NULL, 0x4a000000);
858   - if (IS_ERR(main_intc)) {
859   - pr_err("irq: could not create main interrupt controller\n");
860   - return;
861   - }
862   -
863   - s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
864   - s3c24xx_init_intc(NULL, &init_s3c2416subint[0], main_intc, 0x4a000018);
865   -
866   - s3c24xx_init_intc(NULL, &init_s3c2416_second[0], NULL, 0x4a000040);
867   -}
868   -
869   -#endif
870   -
871   -#ifdef CONFIG_CPU_S3C2440
872   -static struct s3c_irq_data init_s3c2440base[32] = {
873   - { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
874   - { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
875   - { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
876   - { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
877   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
878   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
879   - { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
880   - { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
881   - { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
882   - { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
883   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
884   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
885   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
886   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
887   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
888   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
889   - { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
890   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
891   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
892   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
893   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
894   - { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
895   - { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
896   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
897   - { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
898   - { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
899   - { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
900   - { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
901   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
902   - { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
903   - { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
904   - { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
905   -};
906   -
907   -static struct s3c_irq_data init_s3c2440subint[32] = {
908   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
909   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
910   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
911   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
912   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
913   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
914   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
915   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
916   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
917   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
918   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
919   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* TC */
920   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* ADC */
921   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
922   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
923   -};
924   -
925   -void __init s3c2440_init_irq(void)
926   -{
927   - struct s3c_irq_intc *main_intc;
928   -
929   - pr_info("S3C2440: IRQ Support\n");
930   -
931   -#ifdef CONFIG_FIQ
932   - init_FIQ(FIQ_START);
933   -#endif
934   -
935   - main_intc = s3c24xx_init_intc(NULL, &init_s3c2440base[0], NULL, 0x4a000000);
936   - if (IS_ERR(main_intc)) {
937   - pr_err("irq: could not create main interrupt controller\n");
938   - return;
939   - }
940   -
941   - s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
942   - s3c24xx_init_intc(NULL, &init_s3c2440subint[0], main_intc, 0x4a000018);
943   -}
944   -#endif
945   -
946   -#ifdef CONFIG_CPU_S3C2442
947   -static struct s3c_irq_data init_s3c2442base[32] = {
948   - { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
949   - { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
950   - { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
951   - { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
952   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
953   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
954   - { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
955   - { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
956   - { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
957   - { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
958   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
959   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
960   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
961   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
962   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
963   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
964   - { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
965   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
966   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
967   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
968   - { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
969   - { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
970   - { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
971   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
972   - { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
973   - { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
974   - { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
975   - { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
976   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
977   - { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
978   - { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
979   - { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
980   -};
981   -
982   -static struct s3c_irq_data init_s3c2442subint[32] = {
983   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
984   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
985   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
986   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
987   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
988   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
989   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
990   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
991   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
992   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
993   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
994   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* TC */
995   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* ADC */
996   -};
997   -
998   -void __init s3c2442_init_irq(void)
999   -{
1000   - struct s3c_irq_intc *main_intc;
1001   -
1002   - pr_info("S3C2442: IRQ Support\n");
1003   -
1004   -#ifdef CONFIG_FIQ
1005   - init_FIQ(FIQ_START);
1006   -#endif
1007   -
1008   - main_intc = s3c24xx_init_intc(NULL, &init_s3c2442base[0], NULL, 0x4a000000);
1009   - if (IS_ERR(main_intc)) {
1010   - pr_err("irq: could not create main interrupt controller\n");
1011   - return;
1012   - }
1013   -
1014   - s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
1015   - s3c24xx_init_intc(NULL, &init_s3c2442subint[0], main_intc, 0x4a000018);
1016   -}
1017   -#endif
1018   -
1019   -#ifdef CONFIG_CPU_S3C2443
1020   -static struct s3c_irq_data init_s3c2443base[32] = {
1021   - { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
1022   - { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
1023   - { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
1024   - { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
1025   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
1026   - { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
1027   - { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
1028   - { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
1029   - { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
1030   - { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
1031   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
1032   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
1033   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
1034   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
1035   - { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
1036   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
1037   - { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
1038   - { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
1039   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
1040   - { .type = S3C_IRQTYPE_EDGE, }, /* CFON */
1041   - { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
1042   - { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
1043   - { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
1044   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
1045   - { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
1046   - { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
1047   - { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
1048   - { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
1049   - { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
1050   - { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
1051   - { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
1052   - { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
1053   -};
1054   -
1055   -
1056   -static struct s3c_irq_data init_s3c2443subint[32] = {
1057   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
1058   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
1059   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
1060   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
1061   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
1062   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
1063   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
1064   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
1065   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
1066   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
1067   - { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
1068   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
1069   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
1070   - { .type = S3C_IRQTYPE_NONE }, /* reserved */
1071   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */
1072   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
1073   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
1074   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
1075   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
1076   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
1077   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
1078   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
1079   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
1080   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
1081   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
1082   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
1083   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
1084   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
1085   - { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
1086   -};
1087   -
1088   -void __init s3c2443_init_irq(void)
1089   -{
1090   - struct s3c_irq_intc *main_intc;
1091   -
1092   - pr_info("S3C2443: IRQ Support\n");
1093   -
1094   -#ifdef CONFIG_FIQ
1095   - init_FIQ(FIQ_START);
1096   -#endif
1097   -
1098   - main_intc = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL, 0x4a000000);
1099   - if (IS_ERR(main_intc)) {
1100   - pr_err("irq: could not create main interrupt controller\n");
1101   - return;
1102   - }
1103   -
1104   - s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
1105   - s3c24xx_init_intc(NULL, &init_s3c2443subint[0], main_intc, 0x4a000018);
1106   -}
1107   -#endif
drivers/irqchip/Makefile
... ... @@ -2,6 +2,7 @@
2 2  
3 3 obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
4 4 obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o
  5 +obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o
5 6 obj-$(CONFIG_METAG) += irq-metag-ext.o
6 7 obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o
7 8 obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi.o
drivers/irqchip/irq-s3c24xx.c
Changes suppressed. Click to show
  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 +
  29 +#include <asm/exception.h>
  30 +#include <asm/mach/irq.h>
  31 +
  32 +#include <mach/regs-irq.h>
  33 +#include <mach/regs-gpio.h>
  34 +
  35 +#include <plat/cpu.h>
  36 +#include <plat/regs-irqtype.h>
  37 +#include <plat/pm.h>
  38 +
  39 +#define S3C_IRQTYPE_NONE 0
  40 +#define S3C_IRQTYPE_EINT 1
  41 +#define S3C_IRQTYPE_EDGE 2
  42 +#define S3C_IRQTYPE_LEVEL 3
  43 +
  44 +struct s3c_irq_data {
  45 + unsigned int type;
  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 + * Sructure 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 +static void s3c_irq_mask(struct irq_data *data)
  73 +{
  74 + struct s3c_irq_intc *intc = data->domain->host_data;
  75 + struct s3c_irq_intc *parent_intc = intc->parent;
  76 + struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
  77 + struct s3c_irq_data *parent_data;
  78 + unsigned long mask;
  79 + unsigned int irqno;
  80 +
  81 + mask = __raw_readl(intc->reg_mask);
  82 + mask |= (1UL << data->hwirq);
  83 + __raw_writel(mask, intc->reg_mask);
  84 +
  85 + if (parent_intc) {
  86 + parent_data = &parent_intc->irqs[irq_data->parent_irq];
  87 +
  88 + /* check to see if we need to mask the parent IRQ */
  89 + if ((mask & parent_data->sub_bits) == parent_data->sub_bits) {
  90 + irqno = irq_find_mapping(parent_intc->domain,
  91 + irq_data->parent_irq);
  92 + s3c_irq_mask(irq_get_irq_data(irqno));
  93 + }
  94 + }
  95 +}
  96 +
  97 +static void s3c_irq_unmask(struct irq_data *data)
  98 +{
  99 + struct s3c_irq_intc *intc = data->domain->host_data;
  100 + struct s3c_irq_intc *parent_intc = intc->parent;
  101 + struct s3c_irq_data *irq_data = &intc->irqs[data->hwirq];
  102 + unsigned long mask;
  103 + unsigned int irqno;
  104 +
  105 + mask = __raw_readl(intc->reg_mask);
  106 + mask &= ~(1UL << data->hwirq);
  107 + __raw_writel(mask, intc->reg_mask);
  108 +
  109 + if (parent_intc) {
  110 + irqno = irq_find_mapping(parent_intc->domain,
  111 + irq_data->parent_irq);
  112 + s3c_irq_unmask(irq_get_irq_data(irqno));
  113 + }
  114 +}
  115 +
  116 +static inline void s3c_irq_ack(struct irq_data *data)
  117 +{
  118 + struct s3c_irq_intc *intc = data->domain->host_data;
  119 + unsigned long bitval = 1UL << data->hwirq;
  120 +
  121 + __raw_writel(bitval, intc->reg_pending);
  122 + if (intc->reg_intpnd)
  123 + __raw_writel(bitval, intc->reg_intpnd);
  124 +}
  125 +
  126 +static int s3c_irqext_type_set(void __iomem *gpcon_reg,
  127 + void __iomem *extint_reg,
  128 + unsigned long gpcon_offset,
  129 + unsigned long extint_offset,
  130 + unsigned int type)
  131 +{
  132 + unsigned long newvalue = 0, value;
  133 +
  134 + /* Set the GPIO to external interrupt mode */
  135 + value = __raw_readl(gpcon_reg);
  136 + value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
  137 + __raw_writel(value, gpcon_reg);
  138 +
  139 + /* Set the external interrupt to pointed trigger type */
  140 + switch (type)
  141 + {
  142 + case IRQ_TYPE_NONE:
  143 + pr_warn("No edge setting!\n");
  144 + break;
  145 +
  146 + case IRQ_TYPE_EDGE_RISING:
  147 + newvalue = S3C2410_EXTINT_RISEEDGE;
  148 + break;
  149 +
  150 + case IRQ_TYPE_EDGE_FALLING:
  151 + newvalue = S3C2410_EXTINT_FALLEDGE;
  152 + break;
  153 +
  154 + case IRQ_TYPE_EDGE_BOTH:
  155 + newvalue = S3C2410_EXTINT_BOTHEDGE;
  156 + break;
  157 +
  158 + case IRQ_TYPE_LEVEL_LOW:
  159 + newvalue = S3C2410_EXTINT_LOWLEV;
  160 + break;
  161 +
  162 + case IRQ_TYPE_LEVEL_HIGH:
  163 + newvalue = S3C2410_EXTINT_HILEV;
  164 + break;
  165 +
  166 + default:
  167 + pr_err("No such irq type %d", type);
  168 + return -EINVAL;
  169 + }
  170 +
  171 + value = __raw_readl(extint_reg);
  172 + value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
  173 + __raw_writel(value, extint_reg);
  174 +
  175 + return 0;
  176 +}
  177 +
  178 +static int s3c_irqext_type(struct irq_data *data, unsigned int type)
  179 +{
  180 + void __iomem *extint_reg;
  181 + void __iomem *gpcon_reg;
  182 + unsigned long gpcon_offset, extint_offset;
  183 +
  184 + if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
  185 + gpcon_reg = S3C2410_GPFCON;
  186 + extint_reg = S3C24XX_EXTINT0;
  187 + gpcon_offset = (data->hwirq) * 2;
  188 + extint_offset = (data->hwirq) * 4;
  189 + } else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
  190 + gpcon_reg = S3C2410_GPGCON;
  191 + extint_reg = S3C24XX_EXTINT1;
  192 + gpcon_offset = (data->hwirq - 8) * 2;
  193 + extint_offset = (data->hwirq - 8) * 4;
  194 + } else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
  195 + gpcon_reg = S3C2410_GPGCON;
  196 + extint_reg = S3C24XX_EXTINT2;
  197 + gpcon_offset = (data->hwirq - 8) * 2;
  198 + extint_offset = (data->hwirq - 16) * 4;
  199 + } else {
  200 + return -EINVAL;
  201 + }
  202 +
  203 + return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
  204 + extint_offset, type);
  205 +}
  206 +
  207 +static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
  208 +{
  209 + void __iomem *extint_reg;
  210 + void __iomem *gpcon_reg;
  211 + unsigned long gpcon_offset, extint_offset;
  212 +
  213 + if ((data->hwirq >= 0) && (data->hwirq <= 3)) {
  214 + gpcon_reg = S3C2410_GPFCON;
  215 + extint_reg = S3C24XX_EXTINT0;
  216 + gpcon_offset = (data->hwirq) * 2;
  217 + extint_offset = (data->hwirq) * 4;
  218 + } else {
  219 + return -EINVAL;
  220 + }
  221 +
  222 + return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
  223 + extint_offset, type);
  224 +}
  225 +
  226 +static struct irq_chip s3c_irq_chip = {
  227 + .name = "s3c",
  228 + .irq_ack = s3c_irq_ack,
  229 + .irq_mask = s3c_irq_mask,
  230 + .irq_unmask = s3c_irq_unmask,
  231 + .irq_set_wake = s3c_irq_wake
  232 +};
  233 +
  234 +static struct irq_chip s3c_irq_level_chip = {
  235 + .name = "s3c-level",
  236 + .irq_mask = s3c_irq_mask,
  237 + .irq_unmask = s3c_irq_unmask,
  238 + .irq_ack = s3c_irq_ack,
  239 +};
  240 +
  241 +static struct irq_chip s3c_irqext_chip = {
  242 + .name = "s3c-ext",
  243 + .irq_mask = s3c_irq_mask,
  244 + .irq_unmask = s3c_irq_unmask,
  245 + .irq_ack = s3c_irq_ack,
  246 + .irq_set_type = s3c_irqext_type,
  247 + .irq_set_wake = s3c_irqext_wake
  248 +};
  249 +
  250 +static struct irq_chip s3c_irq_eint0t4 = {
  251 + .name = "s3c-ext0",
  252 + .irq_ack = s3c_irq_ack,
  253 + .irq_mask = s3c_irq_mask,
  254 + .irq_unmask = s3c_irq_unmask,
  255 + .irq_set_wake = s3c_irq_wake,
  256 + .irq_set_type = s3c_irqext0_type,
  257 +};
  258 +
  259 +static void s3c_irq_demux(unsigned int irq, struct irq_desc *desc)
  260 +{
  261 + struct irq_chip *chip = irq_desc_get_chip(desc);
  262 + struct s3c_irq_intc *intc = desc->irq_data.domain->host_data;
  263 + struct s3c_irq_data *irq_data = &intc->irqs[desc->irq_data.hwirq];
  264 + struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
  265 + unsigned long src;
  266 + unsigned long msk;
  267 + unsigned int n;
  268 +
  269 + chained_irq_enter(chip, desc);
  270 +
  271 + src = __raw_readl(sub_intc->reg_pending);
  272 + msk = __raw_readl(sub_intc->reg_mask);
  273 +
  274 + src &= ~msk;
  275 + src &= irq_data->sub_bits;
  276 +
  277 + while (src) {
  278 + n = __ffs(src);
  279 + src &= ~(1 << n);
  280 + generic_handle_irq(irq_find_mapping(sub_intc->domain, n));
  281 + }
  282 +
  283 + chained_irq_exit(chip, desc);
  284 +}
  285 +
  286 +static struct s3c_irq_intc *main_intc;
  287 +static struct s3c_irq_intc *main_intc2;
  288 +
  289 +static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
  290 + struct pt_regs *regs)
  291 +{
  292 + int pnd;
  293 + int offset;
  294 + int irq;
  295 +
  296 + pnd = __raw_readl(intc->reg_intpnd);
  297 + if (!pnd)
  298 + return false;
  299 +
  300 + /* We have a problem that the INTOFFSET register does not always
  301 + * show one interrupt. Occasionally we get two interrupts through
  302 + * the prioritiser, and this causes the INTOFFSET register to show
  303 + * what looks like the logical-or of the two interrupt numbers.
  304 + *
  305 + * Thanks to Klaus, Shannon, et al for helping to debug this problem
  306 + */
  307 + offset = __raw_readl(intc->reg_intpnd + 4);
  308 +
  309 + /* Find the bit manually, when the offset is wrong.
  310 + * The pending register only ever contains the one bit of the next
  311 + * interrupt to handle.
  312 + */
  313 + if (!(pnd & (1 << offset)))
  314 + offset = __ffs(pnd);
  315 +
  316 + irq = irq_find_mapping(intc->domain, offset);
  317 + handle_IRQ(irq, regs);
  318 + return true;
  319 +}
  320 +
  321 +asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs)
  322 +{
  323 + do {
  324 + if (likely(main_intc))
  325 + if (s3c24xx_handle_intc(main_intc, regs))
  326 + continue;
  327 +
  328 + if (main_intc2)
  329 + if (s3c24xx_handle_intc(main_intc2, regs))
  330 + continue;
  331 +
  332 + break;
  333 + } while (1);
  334 +}
  335 +
  336 +#ifdef CONFIG_FIQ
  337 +/**
  338 + * s3c24xx_set_fiq - set the FIQ routing
  339 + * @irq: IRQ number to route to FIQ on processor.
  340 + * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
  341 + *
  342 + * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
  343 + * @on is true, the @irq is checked to see if it can be routed and the
  344 + * interrupt controller updated to route the IRQ. If @on is false, the FIQ
  345 + * routing is cleared, regardless of which @irq is specified.
  346 + */
  347 +int s3c24xx_set_fiq(unsigned int irq, bool on)
  348 +{
  349 + u32 intmod;
  350 + unsigned offs;
  351 +
  352 + if (on) {
  353 + offs = irq - FIQ_START;
  354 + if (offs > 31)
  355 + return -EINVAL;
  356 +
  357 + intmod = 1 << offs;
  358 + } else {
  359 + intmod = 0;
  360 + }
  361 +
  362 + __raw_writel(intmod, S3C2410_INTMOD);
  363 + return 0;
  364 +}
  365 +
  366 +EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
  367 +#endif
  368 +
  369 +static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
  370 + irq_hw_number_t hw)
  371 +{
  372 + struct s3c_irq_intc *intc = h->host_data;
  373 + struct s3c_irq_data *irq_data = &intc->irqs[hw];
  374 + struct s3c_irq_intc *parent_intc;
  375 + struct s3c_irq_data *parent_irq_data;
  376 + unsigned int irqno;
  377 +
  378 + /* attach controller pointer to irq_data */
  379 + irq_data->intc = intc;
  380 +
  381 + parent_intc = intc->parent;
  382 +
  383 + /* set handler and flags */
  384 + switch (irq_data->type) {
  385 + case S3C_IRQTYPE_NONE:
  386 + return 0;
  387 + case S3C_IRQTYPE_EINT:
  388 + /* On the S3C2412, the EINT0to3 have a parent irq
  389 + * but need the s3c_irq_eint0t4 chip
  390 + */
  391 + if (parent_intc && (!soc_is_s3c2412() || hw >= 4))
  392 + irq_set_chip_and_handler(virq, &s3c_irqext_chip,
  393 + handle_edge_irq);
  394 + else
  395 + irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
  396 + handle_edge_irq);
  397 + break;
  398 + case S3C_IRQTYPE_EDGE:
  399 + if (parent_intc || intc->reg_pending == S3C2416_SRCPND2)
  400 + irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
  401 + handle_edge_irq);
  402 + else
  403 + irq_set_chip_and_handler(virq, &s3c_irq_chip,
  404 + handle_edge_irq);
  405 + break;
  406 + case S3C_IRQTYPE_LEVEL:
  407 + if (parent_intc)
  408 + irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
  409 + handle_level_irq);
  410 + else
  411 + irq_set_chip_and_handler(virq, &s3c_irq_chip,
  412 + handle_level_irq);
  413 + break;
  414 + default:
  415 + pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
  416 + return -EINVAL;
  417 + }
  418 + set_irq_flags(virq, IRQF_VALID);
  419 +
  420 + if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) {
  421 + if (irq_data->parent_irq > 31) {
  422 + pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
  423 + irq_data->parent_irq);
  424 + goto err;
  425 + }
  426 +
  427 + parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
  428 + parent_irq_data->sub_intc = intc;
  429 + parent_irq_data->sub_bits |= (1UL << hw);
  430 +
  431 + /* attach the demuxer to the parent irq */
  432 + irqno = irq_find_mapping(parent_intc->domain,
  433 + irq_data->parent_irq);
  434 + if (!irqno) {
  435 + pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
  436 + irq_data->parent_irq);
  437 + goto err;
  438 + }
  439 + irq_set_chained_handler(irqno, s3c_irq_demux);
  440 + }
  441 +
  442 + return 0;
  443 +
  444 +err:
  445 + set_irq_flags(virq, 0);
  446 +
  447 + /* the only error can result from bad mapping data*/
  448 + return -EINVAL;
  449 +}
  450 +
  451 +static struct irq_domain_ops s3c24xx_irq_ops = {
  452 + .map = s3c24xx_irq_map,
  453 + .xlate = irq_domain_xlate_twocell,
  454 +};
  455 +
  456 +static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
  457 +{
  458 + void __iomem *reg_source;
  459 + unsigned long pend;
  460 + unsigned long last;
  461 + int i;
  462 +
  463 + /* if intpnd is set, read the next pending irq from there */
  464 + reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending;
  465 +
  466 + last = 0;
  467 + for (i = 0; i < 4; i++) {
  468 + pend = __raw_readl(reg_source);
  469 +
  470 + if (pend == 0 || pend == last)
  471 + break;
  472 +
  473 + __raw_writel(pend, intc->reg_pending);
  474 + if (intc->reg_intpnd)
  475 + __raw_writel(pend, intc->reg_intpnd);
  476 +
  477 + pr_info("irq: clearing pending status %08x\n", (int)pend);
  478 + last = pend;
  479 + }
  480 +}
  481 +
  482 +static struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np,
  483 + struct s3c_irq_data *irq_data,
  484 + struct s3c_irq_intc *parent,
  485 + unsigned long address)
  486 +{
  487 + struct s3c_irq_intc *intc;
  488 + void __iomem *base = (void *)0xf6000000; /* static mapping */
  489 + int irq_num;
  490 + int irq_start;
  491 + int ret;
  492 +
  493 + intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
  494 + if (!intc)
  495 + return ERR_PTR(-ENOMEM);
  496 +
  497 + intc->irqs = irq_data;
  498 +
  499 + if (parent)
  500 + intc->parent = parent;
  501 +
  502 + /* select the correct data for the controller.
  503 + * Need to hard code the irq num start and offset
  504 + * to preserve the static mapping for now
  505 + */
  506 + switch (address) {
  507 + case 0x4a000000:
  508 + pr_debug("irq: found main intc\n");
  509 + intc->reg_pending = base;
  510 + intc->reg_mask = base + 0x08;
  511 + intc->reg_intpnd = base + 0x10;
  512 + irq_num = 32;
  513 + irq_start = S3C2410_IRQ(0);
  514 + break;
  515 + case 0x4a000018:
  516 + pr_debug("irq: found subintc\n");
  517 + intc->reg_pending = base + 0x18;
  518 + intc->reg_mask = base + 0x1c;
  519 + irq_num = 29;
  520 + irq_start = S3C2410_IRQSUB(0);
  521 + break;
  522 + case 0x4a000040:
  523 + pr_debug("irq: found intc2\n");
  524 + intc->reg_pending = base + 0x40;
  525 + intc->reg_mask = base + 0x48;
  526 + intc->reg_intpnd = base + 0x50;
  527 + irq_num = 8;
  528 + irq_start = S3C2416_IRQ(0);
  529 + break;
  530 + case 0x560000a4:
  531 + pr_debug("irq: found eintc\n");
  532 + base = (void *)0xfd000000;
  533 +
  534 + intc->reg_mask = base + 0xa4;
  535 + intc->reg_pending = base + 0x08;
  536 + irq_num = 24;
  537 + irq_start = S3C2410_IRQ(32);
  538 + break;
  539 + default:
  540 + pr_err("irq: unsupported controller address\n");
  541 + ret = -EINVAL;
  542 + goto err;
  543 + }
  544 +
  545 + /* now that all the data is complete, init the irq-domain */
  546 + s3c24xx_clear_intc(intc);
  547 + intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
  548 + 0, &s3c24xx_irq_ops,
  549 + intc);
  550 + if (!intc->domain) {
  551 + pr_err("irq: could not create irq-domain\n");
  552 + ret = -EINVAL;
  553 + goto err;
  554 + }
  555 +
  556 + if (address == 0x4a000000)
  557 + main_intc = intc;
  558 + else if (address == 0x4a000040)
  559 + main_intc2 = intc;
  560 +
  561 + set_handle_irq(s3c24xx_handle_irq);
  562 +
  563 + return intc;
  564 +
  565 +err:
  566 + kfree(intc);
  567 + return ERR_PTR(ret);
  568 +}
  569 +
  570 +static struct s3c_irq_data init_eint[32] = {
  571 + { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  572 + { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  573 + { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  574 + { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  575 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
  576 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
  577 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
  578 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
  579 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
  580 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
  581 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
  582 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
  583 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
  584 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
  585 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
  586 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
  587 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
  588 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
  589 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
  590 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
  591 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
  592 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
  593 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
  594 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
  595 +};
  596 +
  597 +#ifdef CONFIG_CPU_S3C2410
  598 +static struct s3c_irq_data init_s3c2410base[32] = {
  599 + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  600 + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  601 + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  602 + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  603 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  604 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  605 + { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  606 + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  607 + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  608 + { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  609 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  610 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  611 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  612 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  613 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  614 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  615 + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  616 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  617 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  618 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  619 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  620 + { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  621 + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  622 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  623 + { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  624 + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  625 + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  626 + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  627 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  628 + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  629 + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  630 + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  631 +};
  632 +
  633 +static struct s3c_irq_data init_s3c2410subint[32] = {
  634 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  635 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  636 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  637 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  638 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  639 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  640 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  641 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  642 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  643 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  644 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  645 +};
  646 +
  647 +void __init s3c2410_init_irq(void)
  648 +{
  649 + struct s3c_irq_intc *main_intc;
  650 +
  651 +#ifdef CONFIG_FIQ
  652 + init_FIQ(FIQ_START);
  653 +#endif
  654 +
  655 + main_intc = s3c24xx_init_intc(NULL, &init_s3c2410base[0], NULL, 0x4a000000);
  656 + if (IS_ERR(main_intc)) {
  657 + pr_err("irq: could not create main interrupt controller\n");
  658 + return;
  659 + }
  660 +
  661 + s3c24xx_init_intc(NULL, &init_s3c2410subint[0], main_intc, 0x4a000018);
  662 + s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  663 +}
  664 +#endif
  665 +
  666 +#ifdef CONFIG_CPU_S3C2412
  667 +static struct s3c_irq_data init_s3c2412base[32] = {
  668 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT0 */
  669 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT1 */
  670 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT2 */
  671 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT3 */
  672 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  673 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  674 + { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  675 + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  676 + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  677 + { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  678 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  679 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  680 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  681 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  682 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  683 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  684 + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  685 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  686 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  687 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  688 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  689 + { .type = S3C_IRQTYPE_LEVEL, }, /* SDI/CF */
  690 + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  691 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  692 + { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  693 + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  694 + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  695 + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  696 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  697 + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  698 + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  699 + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  700 +};
  701 +
  702 +static struct s3c_irq_data init_s3c2412eint[32] = {
  703 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 0 }, /* EINT0 */
  704 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 1 }, /* EINT1 */
  705 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 2 }, /* EINT2 */
  706 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 3 }, /* EINT3 */
  707 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT4 */
  708 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT5 */
  709 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT6 */
  710 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 }, /* EINT7 */
  711 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT8 */
  712 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT9 */
  713 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT10 */
  714 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT11 */
  715 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT12 */
  716 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT13 */
  717 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT14 */
  718 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT15 */
  719 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT16 */
  720 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT17 */
  721 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT18 */
  722 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT19 */
  723 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT20 */
  724 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT21 */
  725 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT22 */
  726 + { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 }, /* EINT23 */
  727 +};
  728 +
  729 +static struct s3c_irq_data init_s3c2412subint[32] = {
  730 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  731 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  732 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  733 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  734 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  735 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  736 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  737 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  738 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  739 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  740 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  741 + { .type = S3C_IRQTYPE_NONE, },
  742 + { .type = S3C_IRQTYPE_NONE, },
  743 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* SDI */
  744 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 }, /* CF */
  745 +};
  746 +
  747 +void s3c2412_init_irq(void)
  748 +{
  749 + struct s3c_irq_intc *main_intc;
  750 +
  751 + pr_info("S3C2412: IRQ Support\n");
  752 +
  753 +#ifdef CONFIG_FIQ
  754 + init_FIQ(FIQ_START);
  755 +#endif
  756 +
  757 + main_intc = s3c24xx_init_intc(NULL, &init_s3c2412base[0], NULL, 0x4a000000);
  758 + if (IS_ERR(main_intc)) {
  759 + pr_err("irq: could not create main interrupt controller\n");
  760 + return;
  761 + }
  762 +
  763 + s3c24xx_init_intc(NULL, &init_s3c2412eint[0], main_intc, 0x560000a4);
  764 + s3c24xx_init_intc(NULL, &init_s3c2412subint[0], main_intc, 0x4a000018);
  765 +}
  766 +#endif
  767 +
  768 +#ifdef CONFIG_CPU_S3C2416
  769 +static struct s3c_irq_data init_s3c2416base[32] = {
  770 + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  771 + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  772 + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  773 + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  774 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  775 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  776 + { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  777 + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  778 + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  779 + { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  780 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  781 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  782 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  783 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  784 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  785 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  786 + { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
  787 + { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
  788 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
  789 + { .type = S3C_IRQTYPE_NONE, }, /* reserved */
  790 + { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
  791 + { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
  792 + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  793 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  794 + { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
  795 + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  796 + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  797 + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  798 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  799 + { .type = S3C_IRQTYPE_NONE, },
  800 + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  801 + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  802 +};
  803 +
  804 +static struct s3c_irq_data init_s3c2416subint[32] = {
  805 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  806 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  807 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  808 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  809 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  810 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  811 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  812 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  813 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  814 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  815 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  816 + { .type = S3C_IRQTYPE_NONE }, /* reserved */
  817 + { .type = S3C_IRQTYPE_NONE }, /* reserved */
  818 + { .type = S3C_IRQTYPE_NONE }, /* reserved */
  819 + { .type = S3C_IRQTYPE_NONE }, /* reserved */
  820 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
  821 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
  822 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
  823 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
  824 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
  825 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
  826 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
  827 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
  828 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
  829 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
  830 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
  831 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
  832 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  833 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  834 +};
  835 +
  836 +static struct s3c_irq_data init_s3c2416_second[32] = {
  837 + { .type = S3C_IRQTYPE_EDGE }, /* 2D */
  838 + { .type = S3C_IRQTYPE_EDGE }, /* IIC1 */
  839 + { .type = S3C_IRQTYPE_NONE }, /* reserved */
  840 + { .type = S3C_IRQTYPE_NONE }, /* reserved */
  841 + { .type = S3C_IRQTYPE_EDGE }, /* PCM0 */
  842 + { .type = S3C_IRQTYPE_EDGE }, /* PCM1 */
  843 + { .type = S3C_IRQTYPE_EDGE }, /* I2S0 */
  844 + { .type = S3C_IRQTYPE_EDGE }, /* I2S1 */
  845 +};
  846 +
  847 +void __init s3c2416_init_irq(void)
  848 +{
  849 + struct s3c_irq_intc *main_intc;
  850 +
  851 + pr_info("S3C2416: IRQ Support\n");
  852 +
  853 +#ifdef CONFIG_FIQ
  854 + init_FIQ(FIQ_START);
  855 +#endif
  856 +
  857 + main_intc = s3c24xx_init_intc(NULL, &init_s3c2416base[0], NULL, 0x4a000000);
  858 + if (IS_ERR(main_intc)) {
  859 + pr_err("irq: could not create main interrupt controller\n");
  860 + return;
  861 + }
  862 +
  863 + s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  864 + s3c24xx_init_intc(NULL, &init_s3c2416subint[0], main_intc, 0x4a000018);
  865 +
  866 + s3c24xx_init_intc(NULL, &init_s3c2416_second[0], NULL, 0x4a000040);
  867 +}
  868 +
  869 +#endif
  870 +
  871 +#ifdef CONFIG_CPU_S3C2440
  872 +static struct s3c_irq_data init_s3c2440base[32] = {
  873 + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  874 + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  875 + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  876 + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  877 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  878 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  879 + { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  880 + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  881 + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  882 + { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  883 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  884 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  885 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  886 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  887 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  888 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  889 + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  890 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  891 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  892 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  893 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  894 + { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  895 + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  896 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  897 + { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
  898 + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  899 + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  900 + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  901 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  902 + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  903 + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  904 + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  905 +};
  906 +
  907 +static struct s3c_irq_data init_s3c2440subint[32] = {
  908 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  909 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  910 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  911 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  912 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  913 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  914 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  915 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  916 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  917 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  918 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  919 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* TC */
  920 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* ADC */
  921 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  922 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  923 +};
  924 +
  925 +void __init s3c2440_init_irq(void)
  926 +{
  927 + struct s3c_irq_intc *main_intc;
  928 +
  929 + pr_info("S3C2440: IRQ Support\n");
  930 +
  931 +#ifdef CONFIG_FIQ
  932 + init_FIQ(FIQ_START);
  933 +#endif
  934 +
  935 + main_intc = s3c24xx_init_intc(NULL, &init_s3c2440base[0], NULL, 0x4a000000);
  936 + if (IS_ERR(main_intc)) {
  937 + pr_err("irq: could not create main interrupt controller\n");
  938 + return;
  939 + }
  940 +
  941 + s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  942 + s3c24xx_init_intc(NULL, &init_s3c2440subint[0], main_intc, 0x4a000018);
  943 +}
  944 +#endif
  945 +
  946 +#ifdef CONFIG_CPU_S3C2442
  947 +static struct s3c_irq_data init_s3c2442base[32] = {
  948 + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  949 + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  950 + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  951 + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  952 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  953 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  954 + { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  955 + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  956 + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  957 + { .type = S3C_IRQTYPE_EDGE, }, /* WDT */
  958 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  959 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  960 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  961 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  962 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  963 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  964 + { .type = S3C_IRQTYPE_EDGE, }, /* LCD */
  965 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA0 */
  966 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA1 */
  967 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA2 */
  968 + { .type = S3C_IRQTYPE_EDGE, }, /* DMA3 */
  969 + { .type = S3C_IRQTYPE_EDGE, }, /* SDI */
  970 + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  971 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  972 + { .type = S3C_IRQTYPE_LEVEL, }, /* NFCON */
  973 + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  974 + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  975 + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  976 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  977 + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  978 + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  979 + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  980 +};
  981 +
  982 +static struct s3c_irq_data init_s3c2442subint[32] = {
  983 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  984 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  985 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  986 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  987 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  988 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  989 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  990 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  991 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  992 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  993 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  994 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* TC */
  995 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* ADC */
  996 +};
  997 +
  998 +void __init s3c2442_init_irq(void)
  999 +{
  1000 + struct s3c_irq_intc *main_intc;
  1001 +
  1002 + pr_info("S3C2442: IRQ Support\n");
  1003 +
  1004 +#ifdef CONFIG_FIQ
  1005 + init_FIQ(FIQ_START);
  1006 +#endif
  1007 +
  1008 + main_intc = s3c24xx_init_intc(NULL, &init_s3c2442base[0], NULL, 0x4a000000);
  1009 + if (IS_ERR(main_intc)) {
  1010 + pr_err("irq: could not create main interrupt controller\n");
  1011 + return;
  1012 + }
  1013 +
  1014 + s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  1015 + s3c24xx_init_intc(NULL, &init_s3c2442subint[0], main_intc, 0x4a000018);
  1016 +}
  1017 +#endif
  1018 +
  1019 +#ifdef CONFIG_CPU_S3C2443
  1020 +static struct s3c_irq_data init_s3c2443base[32] = {
  1021 + { .type = S3C_IRQTYPE_EINT, }, /* EINT0 */
  1022 + { .type = S3C_IRQTYPE_EINT, }, /* EINT1 */
  1023 + { .type = S3C_IRQTYPE_EINT, }, /* EINT2 */
  1024 + { .type = S3C_IRQTYPE_EINT, }, /* EINT3 */
  1025 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT4to7 */
  1026 + { .type = S3C_IRQTYPE_LEVEL, }, /* EINT8to23 */
  1027 + { .type = S3C_IRQTYPE_LEVEL, }, /* CAM */
  1028 + { .type = S3C_IRQTYPE_EDGE, }, /* nBATT_FLT */
  1029 + { .type = S3C_IRQTYPE_EDGE, }, /* TICK */
  1030 + { .type = S3C_IRQTYPE_LEVEL, }, /* WDT/AC97 */
  1031 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER0 */
  1032 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER1 */
  1033 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER2 */
  1034 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER3 */
  1035 + { .type = S3C_IRQTYPE_EDGE, }, /* TIMER4 */
  1036 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART2 */
  1037 + { .type = S3C_IRQTYPE_LEVEL, }, /* LCD */
  1038 + { .type = S3C_IRQTYPE_LEVEL, }, /* DMA */
  1039 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART3 */
  1040 + { .type = S3C_IRQTYPE_EDGE, }, /* CFON */
  1041 + { .type = S3C_IRQTYPE_EDGE, }, /* SDI1 */
  1042 + { .type = S3C_IRQTYPE_EDGE, }, /* SDI0 */
  1043 + { .type = S3C_IRQTYPE_EDGE, }, /* SPI0 */
  1044 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART1 */
  1045 + { .type = S3C_IRQTYPE_EDGE, }, /* NAND */
  1046 + { .type = S3C_IRQTYPE_EDGE, }, /* USBD */
  1047 + { .type = S3C_IRQTYPE_EDGE, }, /* USBH */
  1048 + { .type = S3C_IRQTYPE_EDGE, }, /* IIC */
  1049 + { .type = S3C_IRQTYPE_LEVEL, }, /* UART0 */
  1050 + { .type = S3C_IRQTYPE_EDGE, }, /* SPI1 */
  1051 + { .type = S3C_IRQTYPE_EDGE, }, /* RTC */
  1052 + { .type = S3C_IRQTYPE_LEVEL, }, /* ADCPARENT */
  1053 +};
  1054 +
  1055 +
  1056 +static struct s3c_irq_data init_s3c2443subint[32] = {
  1057 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-RX */
  1058 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-TX */
  1059 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 }, /* UART0-ERR */
  1060 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-RX */
  1061 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-TX */
  1062 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 }, /* UART1-ERR */
  1063 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-RX */
  1064 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-TX */
  1065 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 }, /* UART2-ERR */
  1066 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* TC */
  1067 + { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 }, /* ADC */
  1068 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_C */
  1069 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 }, /* CAM_P */
  1070 + { .type = S3C_IRQTYPE_NONE }, /* reserved */
  1071 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD1 */
  1072 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD2 */
  1073 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD3 */
  1074 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 }, /* LCD4 */
  1075 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA0 */
  1076 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA1 */
  1077 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA2 */
  1078 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA3 */
  1079 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA4 */
  1080 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 }, /* DMA5 */
  1081 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-RX */
  1082 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-TX */
  1083 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 }, /* UART3-ERR */
  1084 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* WDT */
  1085 + { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 }, /* AC97 */
  1086 +};
  1087 +
  1088 +void __init s3c2443_init_irq(void)
  1089 +{
  1090 + struct s3c_irq_intc *main_intc;
  1091 +
  1092 + pr_info("S3C2443: IRQ Support\n");
  1093 +
  1094 +#ifdef CONFIG_FIQ
  1095 + init_FIQ(FIQ_START);
  1096 +#endif
  1097 +
  1098 + main_intc = s3c24xx_init_intc(NULL, &init_s3c2443base[0], NULL, 0x4a000000);
  1099 + if (IS_ERR(main_intc)) {
  1100 + pr_err("irq: could not create main interrupt controller\n");
  1101 + return;
  1102 + }
  1103 +
  1104 + s3c24xx_init_intc(NULL, &init_eint[0], main_intc, 0x560000a4);
  1105 + s3c24xx_init_intc(NULL, &init_s3c2443subint[0], main_intc, 0x4a000018);
  1106 +}
  1107 +#endif