0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/init.h>
0011 #include <linux/slab.h>
0012 #include <linux/module.h>
0013 #include <linux/io.h>
0014 #include <linux/err.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/ioport.h>
0017 #include <linux/device.h>
0018 #include <linux/irqdomain.h>
0019 #include <linux/irqchip.h>
0020 #include <linux/irqchip/chained_irq.h>
0021 #include <linux/of.h>
0022 #include <linux/of_irq.h>
0023 #include <linux/of_address.h>
0024 #include <linux/spi/s3c24xx.h>
0025
0026 #include <asm/exception.h>
0027 #include <asm/mach/irq.h>
0028
0029 #include "irqs.h"
0030 #include "regs-irq.h"
0031 #include "regs-gpio.h"
0032
0033 #include "cpu.h"
0034 #include "regs-irqtype.h"
0035 #include "pm.h"
0036 #include "s3c24xx.h"
0037
0038 #define S3C_IRQTYPE_NONE 0
0039 #define S3C_IRQTYPE_EINT 1
0040 #define S3C_IRQTYPE_EDGE 2
0041 #define S3C_IRQTYPE_LEVEL 3
0042
0043 struct s3c_irq_data {
0044 unsigned int type;
0045 unsigned long offset;
0046 unsigned long parent_irq;
0047
0048
0049 struct s3c_irq_intc *intc;
0050 unsigned long sub_bits;
0051 struct s3c_irq_intc *sub_intc;
0052 };
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 struct s3c_irq_intc {
0064 void __iomem *reg_pending;
0065 void __iomem *reg_intpnd;
0066 void __iomem *reg_mask;
0067 struct irq_domain *domain;
0068 struct s3c_irq_intc *parent;
0069 struct s3c_irq_data *irqs;
0070 };
0071
0072
0073
0074
0075
0076
0077
0078 static struct s3c_irq_intc *s3c_intc[3];
0079
0080 static void s3c_irq_mask(struct irq_data *data)
0081 {
0082 struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
0083 struct s3c_irq_intc *intc = irq_data->intc;
0084 struct s3c_irq_intc *parent_intc = intc->parent;
0085 struct s3c_irq_data *parent_data;
0086 unsigned long mask;
0087 unsigned int irqno;
0088
0089 mask = readl_relaxed(intc->reg_mask);
0090 mask |= (1UL << irq_data->offset);
0091 writel_relaxed(mask, intc->reg_mask);
0092
0093 if (parent_intc) {
0094 parent_data = &parent_intc->irqs[irq_data->parent_irq];
0095
0096
0097
0098
0099
0100 if ((mask & parent_data->sub_bits) == parent_data->sub_bits) {
0101 irqno = irq_find_mapping(parent_intc->domain,
0102 irq_data->parent_irq);
0103 s3c_irq_mask(irq_get_irq_data(irqno));
0104 }
0105 }
0106 }
0107
0108 static void s3c_irq_unmask(struct irq_data *data)
0109 {
0110 struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
0111 struct s3c_irq_intc *intc = irq_data->intc;
0112 struct s3c_irq_intc *parent_intc = intc->parent;
0113 unsigned long mask;
0114 unsigned int irqno;
0115
0116 mask = readl_relaxed(intc->reg_mask);
0117 mask &= ~(1UL << irq_data->offset);
0118 writel_relaxed(mask, intc->reg_mask);
0119
0120 if (parent_intc) {
0121 irqno = irq_find_mapping(parent_intc->domain,
0122 irq_data->parent_irq);
0123 s3c_irq_unmask(irq_get_irq_data(irqno));
0124 }
0125 }
0126
0127 static inline void s3c_irq_ack(struct irq_data *data)
0128 {
0129 struct s3c_irq_data *irq_data = irq_data_get_irq_chip_data(data);
0130 struct s3c_irq_intc *intc = irq_data->intc;
0131 unsigned long bitval = 1UL << irq_data->offset;
0132
0133 writel_relaxed(bitval, intc->reg_pending);
0134 if (intc->reg_intpnd)
0135 writel_relaxed(bitval, intc->reg_intpnd);
0136 }
0137
0138 static int s3c_irq_type(struct irq_data *data, unsigned int type)
0139 {
0140 switch (type) {
0141 case IRQ_TYPE_NONE:
0142 break;
0143 case IRQ_TYPE_EDGE_RISING:
0144 case IRQ_TYPE_EDGE_FALLING:
0145 case IRQ_TYPE_EDGE_BOTH:
0146 irq_set_handler(data->irq, handle_edge_irq);
0147 break;
0148 case IRQ_TYPE_LEVEL_LOW:
0149 case IRQ_TYPE_LEVEL_HIGH:
0150 irq_set_handler(data->irq, handle_level_irq);
0151 break;
0152 default:
0153 pr_err("No such irq type %d\n", type);
0154 return -EINVAL;
0155 }
0156
0157 return 0;
0158 }
0159
0160 static int s3c_irqext_type_set(void __iomem *gpcon_reg,
0161 void __iomem *extint_reg,
0162 unsigned long gpcon_offset,
0163 unsigned long extint_offset,
0164 unsigned int type)
0165 {
0166 unsigned long newvalue = 0, value;
0167
0168
0169 value = readl_relaxed(gpcon_reg);
0170 value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
0171 writel_relaxed(value, gpcon_reg);
0172
0173
0174 switch (type)
0175 {
0176 case IRQ_TYPE_NONE:
0177 pr_warn("No edge setting!\n");
0178 break;
0179
0180 case IRQ_TYPE_EDGE_RISING:
0181 newvalue = S3C2410_EXTINT_RISEEDGE;
0182 break;
0183
0184 case IRQ_TYPE_EDGE_FALLING:
0185 newvalue = S3C2410_EXTINT_FALLEDGE;
0186 break;
0187
0188 case IRQ_TYPE_EDGE_BOTH:
0189 newvalue = S3C2410_EXTINT_BOTHEDGE;
0190 break;
0191
0192 case IRQ_TYPE_LEVEL_LOW:
0193 newvalue = S3C2410_EXTINT_LOWLEV;
0194 break;
0195
0196 case IRQ_TYPE_LEVEL_HIGH:
0197 newvalue = S3C2410_EXTINT_HILEV;
0198 break;
0199
0200 default:
0201 pr_err("No such irq type %d\n", type);
0202 return -EINVAL;
0203 }
0204
0205 value = readl_relaxed(extint_reg);
0206 value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
0207 writel_relaxed(value, extint_reg);
0208
0209 return 0;
0210 }
0211
0212 static int s3c_irqext_type(struct irq_data *data, unsigned int type)
0213 {
0214 void __iomem *extint_reg;
0215 void __iomem *gpcon_reg;
0216 unsigned long gpcon_offset, extint_offset;
0217
0218 if ((data->hwirq >= 4) && (data->hwirq <= 7)) {
0219 gpcon_reg = S3C2410_GPFCON;
0220 extint_reg = S3C24XX_EXTINT0;
0221 gpcon_offset = (data->hwirq) * 2;
0222 extint_offset = (data->hwirq) * 4;
0223 } else if ((data->hwirq >= 8) && (data->hwirq <= 15)) {
0224 gpcon_reg = S3C2410_GPGCON;
0225 extint_reg = S3C24XX_EXTINT1;
0226 gpcon_offset = (data->hwirq - 8) * 2;
0227 extint_offset = (data->hwirq - 8) * 4;
0228 } else if ((data->hwirq >= 16) && (data->hwirq <= 23)) {
0229 gpcon_reg = S3C2410_GPGCON;
0230 extint_reg = S3C24XX_EXTINT2;
0231 gpcon_offset = (data->hwirq - 8) * 2;
0232 extint_offset = (data->hwirq - 16) * 4;
0233 } else {
0234 return -EINVAL;
0235 }
0236
0237 return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
0238 extint_offset, type);
0239 }
0240
0241 static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
0242 {
0243 void __iomem *extint_reg;
0244 void __iomem *gpcon_reg;
0245 unsigned long gpcon_offset, extint_offset;
0246
0247 if (data->hwirq <= 3) {
0248 gpcon_reg = S3C2410_GPFCON;
0249 extint_reg = S3C24XX_EXTINT0;
0250 gpcon_offset = (data->hwirq) * 2;
0251 extint_offset = (data->hwirq) * 4;
0252 } else {
0253 return -EINVAL;
0254 }
0255
0256 return s3c_irqext_type_set(gpcon_reg, extint_reg, gpcon_offset,
0257 extint_offset, type);
0258 }
0259
0260 static struct irq_chip s3c_irq_chip = {
0261 .name = "s3c",
0262 .irq_ack = s3c_irq_ack,
0263 .irq_mask = s3c_irq_mask,
0264 .irq_unmask = s3c_irq_unmask,
0265 .irq_set_type = s3c_irq_type,
0266 .irq_set_wake = s3c_irq_wake
0267 };
0268
0269 static struct irq_chip s3c_irq_level_chip = {
0270 .name = "s3c-level",
0271 .irq_mask = s3c_irq_mask,
0272 .irq_unmask = s3c_irq_unmask,
0273 .irq_ack = s3c_irq_ack,
0274 .irq_set_type = s3c_irq_type,
0275 };
0276
0277 static struct irq_chip s3c_irqext_chip = {
0278 .name = "s3c-ext",
0279 .irq_mask = s3c_irq_mask,
0280 .irq_unmask = s3c_irq_unmask,
0281 .irq_ack = s3c_irq_ack,
0282 .irq_set_type = s3c_irqext_type,
0283 .irq_set_wake = s3c_irqext_wake
0284 };
0285
0286 static struct irq_chip s3c_irq_eint0t4 = {
0287 .name = "s3c-ext0",
0288 .irq_ack = s3c_irq_ack,
0289 .irq_mask = s3c_irq_mask,
0290 .irq_unmask = s3c_irq_unmask,
0291 .irq_set_wake = s3c_irq_wake,
0292 .irq_set_type = s3c_irqext0_type,
0293 };
0294
0295 static void s3c_irq_demux(struct irq_desc *desc)
0296 {
0297 struct irq_chip *chip = irq_desc_get_chip(desc);
0298 struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc);
0299 struct s3c_irq_intc *intc = irq_data->intc;
0300 struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
0301 unsigned int n, offset;
0302 unsigned long src, msk;
0303
0304
0305
0306
0307
0308 offset = irq_domain_get_of_node(intc->domain) ? 32 : 0;
0309
0310 chained_irq_enter(chip, desc);
0311
0312 src = readl_relaxed(sub_intc->reg_pending);
0313 msk = readl_relaxed(sub_intc->reg_mask);
0314
0315 src &= ~msk;
0316 src &= irq_data->sub_bits;
0317
0318 while (src) {
0319 n = __ffs(src);
0320 src &= ~(1 << n);
0321 generic_handle_domain_irq(sub_intc->domain, offset + n);
0322 }
0323
0324 chained_irq_exit(chip, desc);
0325 }
0326
0327 static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc,
0328 struct pt_regs *regs, int intc_offset)
0329 {
0330 int pnd;
0331 int offset;
0332
0333 pnd = readl_relaxed(intc->reg_intpnd);
0334 if (!pnd)
0335 return false;
0336
0337
0338 if (!irq_domain_get_of_node(intc->domain))
0339 intc_offset = 0;
0340
0341
0342
0343
0344
0345
0346
0347
0348 offset = readl_relaxed(intc->reg_intpnd + 4);
0349
0350
0351
0352
0353
0354 if (!(pnd & (1 << offset)))
0355 offset = __ffs(pnd);
0356
0357 generic_handle_domain_irq(intc->domain, intc_offset + offset);
0358 return true;
0359 }
0360
0361 static asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs)
0362 {
0363 do {
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379 if (s3c24xx_handle_intc(s3c_intc[0], regs, 0))
0380 continue;
0381
0382 if (!IS_ERR_OR_NULL(s3c_intc[2]))
0383 if (s3c24xx_handle_intc(s3c_intc[2], regs, 64))
0384 continue;
0385
0386 break;
0387 } while (1);
0388 }
0389
0390 #ifdef CONFIG_FIQ
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404 int s3c24xx_set_fiq(unsigned int irq, u32 *ack_ptr, bool on)
0405 {
0406 u32 intmod;
0407 unsigned offs;
0408
0409 if (on) {
0410 offs = irq - FIQ_START;
0411 if (offs > 31)
0412 return 0;
0413
0414 intmod = 1 << offs;
0415 } else {
0416 intmod = 0;
0417 }
0418
0419 if (ack_ptr)
0420 *ack_ptr = intmod;
0421 writel_relaxed(intmod, S3C2410_INTMOD);
0422
0423 return intmod;
0424 }
0425
0426 EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
0427 #endif
0428
0429 static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
0430 irq_hw_number_t hw)
0431 {
0432 struct s3c_irq_intc *intc = h->host_data;
0433 struct s3c_irq_data *irq_data = &intc->irqs[hw];
0434 struct s3c_irq_intc *parent_intc;
0435 struct s3c_irq_data *parent_irq_data;
0436 unsigned int irqno;
0437
0438
0439 irq_data->intc = intc;
0440 irq_data->offset = hw;
0441
0442 parent_intc = intc->parent;
0443
0444
0445 switch (irq_data->type) {
0446 case S3C_IRQTYPE_NONE:
0447 return 0;
0448 case S3C_IRQTYPE_EINT:
0449
0450
0451
0452 if (parent_intc && (!soc_is_s3c2412() || hw >= 4))
0453 irq_set_chip_and_handler(virq, &s3c_irqext_chip,
0454 handle_edge_irq);
0455 else
0456 irq_set_chip_and_handler(virq, &s3c_irq_eint0t4,
0457 handle_edge_irq);
0458 break;
0459 case S3C_IRQTYPE_EDGE:
0460 if (parent_intc || intc->reg_pending == S3C2416_SRCPND2)
0461 irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
0462 handle_edge_irq);
0463 else
0464 irq_set_chip_and_handler(virq, &s3c_irq_chip,
0465 handle_edge_irq);
0466 break;
0467 case S3C_IRQTYPE_LEVEL:
0468 if (parent_intc)
0469 irq_set_chip_and_handler(virq, &s3c_irq_level_chip,
0470 handle_level_irq);
0471 else
0472 irq_set_chip_and_handler(virq, &s3c_irq_chip,
0473 handle_level_irq);
0474 break;
0475 default:
0476 pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
0477 return -EINVAL;
0478 }
0479
0480 irq_set_chip_data(virq, irq_data);
0481
0482 if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) {
0483 if (irq_data->parent_irq > 31) {
0484 pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
0485 irq_data->parent_irq);
0486 return -EINVAL;
0487 }
0488
0489 parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
0490 parent_irq_data->sub_intc = intc;
0491 parent_irq_data->sub_bits |= (1UL << hw);
0492
0493
0494 irqno = irq_find_mapping(parent_intc->domain,
0495 irq_data->parent_irq);
0496 if (!irqno) {
0497 pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
0498 irq_data->parent_irq);
0499 return -EINVAL;
0500 }
0501 irq_set_chained_handler(irqno, s3c_irq_demux);
0502 }
0503
0504 return 0;
0505 }
0506
0507 static const struct irq_domain_ops s3c24xx_irq_ops = {
0508 .map = s3c24xx_irq_map,
0509 .xlate = irq_domain_xlate_twocell,
0510 };
0511
0512 static void s3c24xx_clear_intc(struct s3c_irq_intc *intc)
0513 {
0514 void __iomem *reg_source;
0515 unsigned long pend;
0516 unsigned long last;
0517 int i;
0518
0519
0520 reg_source = intc->reg_intpnd ? intc->reg_intpnd : intc->reg_pending;
0521
0522 last = 0;
0523 for (i = 0; i < 4; i++) {
0524 pend = readl_relaxed(reg_source);
0525
0526 if (pend == 0 || pend == last)
0527 break;
0528
0529 writel_relaxed(pend, intc->reg_pending);
0530 if (intc->reg_intpnd)
0531 writel_relaxed(pend, intc->reg_intpnd);
0532
0533 pr_info("irq: clearing pending status %08x\n", (int)pend);
0534 last = pend;
0535 }
0536 }
0537
0538 static struct s3c_irq_intc * __init s3c24xx_init_intc(struct device_node *np,
0539 struct s3c_irq_data *irq_data,
0540 struct s3c_irq_intc *parent,
0541 unsigned long address)
0542 {
0543 struct s3c_irq_intc *intc;
0544 void __iomem *base = (void *)0xf6000000;
0545 int irq_num;
0546 int irq_start;
0547 int ret;
0548
0549 intc = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
0550 if (!intc)
0551 return ERR_PTR(-ENOMEM);
0552
0553 intc->irqs = irq_data;
0554
0555 if (parent)
0556 intc->parent = parent;
0557
0558
0559
0560
0561
0562 switch (address) {
0563 case 0x4a000000:
0564 pr_debug("irq: found main intc\n");
0565 intc->reg_pending = base;
0566 intc->reg_mask = base + 0x08;
0567 intc->reg_intpnd = base + 0x10;
0568 irq_num = 32;
0569 irq_start = S3C2410_IRQ(0);
0570 break;
0571 case 0x4a000018:
0572 pr_debug("irq: found subintc\n");
0573 intc->reg_pending = base + 0x18;
0574 intc->reg_mask = base + 0x1c;
0575 irq_num = 29;
0576 irq_start = S3C2410_IRQSUB(0);
0577 break;
0578 case 0x4a000040:
0579 pr_debug("irq: found intc2\n");
0580 intc->reg_pending = base + 0x40;
0581 intc->reg_mask = base + 0x48;
0582 intc->reg_intpnd = base + 0x50;
0583 irq_num = 8;
0584 irq_start = S3C2416_IRQ(0);
0585 break;
0586 case 0x560000a4:
0587 pr_debug("irq: found eintc\n");
0588 base = (void *)0xfd000000;
0589
0590 intc->reg_mask = base + 0xa4;
0591 intc->reg_pending = base + 0xa8;
0592 irq_num = 24;
0593 irq_start = S3C2410_IRQ(32);
0594 break;
0595 default:
0596 pr_err("irq: unsupported controller address\n");
0597 ret = -EINVAL;
0598 goto err;
0599 }
0600
0601
0602 s3c24xx_clear_intc(intc);
0603 intc->domain = irq_domain_add_legacy(np, irq_num, irq_start,
0604 0, &s3c24xx_irq_ops,
0605 intc);
0606 if (!intc->domain) {
0607 pr_err("irq: could not create irq-domain\n");
0608 ret = -EINVAL;
0609 goto err;
0610 }
0611
0612 set_handle_irq(s3c24xx_handle_irq);
0613
0614 return intc;
0615
0616 err:
0617 kfree(intc);
0618 return ERR_PTR(ret);
0619 }
0620
0621 static struct s3c_irq_data __maybe_unused init_eint[32] = {
0622 { .type = S3C_IRQTYPE_NONE, },
0623 { .type = S3C_IRQTYPE_NONE, },
0624 { .type = S3C_IRQTYPE_NONE, },
0625 { .type = S3C_IRQTYPE_NONE, },
0626 { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 },
0627 { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 },
0628 { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 },
0629 { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 },
0630 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0631 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0632 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0633 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0634 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0635 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0636 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0637 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0638 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0639 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0640 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0641 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0642 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0643 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0644 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0645 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0646 };
0647
0648 #ifdef CONFIG_CPU_S3C2410
0649 static struct s3c_irq_data init_s3c2410base[32] = {
0650 { .type = S3C_IRQTYPE_EINT, },
0651 { .type = S3C_IRQTYPE_EINT, },
0652 { .type = S3C_IRQTYPE_EINT, },
0653 { .type = S3C_IRQTYPE_EINT, },
0654 { .type = S3C_IRQTYPE_LEVEL, },
0655 { .type = S3C_IRQTYPE_LEVEL, },
0656 { .type = S3C_IRQTYPE_NONE, },
0657 { .type = S3C_IRQTYPE_EDGE, },
0658 { .type = S3C_IRQTYPE_EDGE, },
0659 { .type = S3C_IRQTYPE_EDGE, },
0660 { .type = S3C_IRQTYPE_EDGE, },
0661 { .type = S3C_IRQTYPE_EDGE, },
0662 { .type = S3C_IRQTYPE_EDGE, },
0663 { .type = S3C_IRQTYPE_EDGE, },
0664 { .type = S3C_IRQTYPE_EDGE, },
0665 { .type = S3C_IRQTYPE_LEVEL, },
0666 { .type = S3C_IRQTYPE_EDGE, },
0667 { .type = S3C_IRQTYPE_EDGE, },
0668 { .type = S3C_IRQTYPE_EDGE, },
0669 { .type = S3C_IRQTYPE_EDGE, },
0670 { .type = S3C_IRQTYPE_EDGE, },
0671 { .type = S3C_IRQTYPE_EDGE, },
0672 { .type = S3C_IRQTYPE_EDGE, },
0673 { .type = S3C_IRQTYPE_LEVEL, },
0674 { .type = S3C_IRQTYPE_NONE, },
0675 { .type = S3C_IRQTYPE_EDGE, },
0676 { .type = S3C_IRQTYPE_EDGE, },
0677 { .type = S3C_IRQTYPE_EDGE, },
0678 { .type = S3C_IRQTYPE_LEVEL, },
0679 { .type = S3C_IRQTYPE_EDGE, },
0680 { .type = S3C_IRQTYPE_EDGE, },
0681 { .type = S3C_IRQTYPE_LEVEL, },
0682 };
0683
0684 static struct s3c_irq_data init_s3c2410subint[32] = {
0685 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0686 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0687 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0688 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0689 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0690 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0691 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0692 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0693 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0694 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
0695 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
0696 };
0697
0698 void __init s3c2410_init_irq(void)
0699 {
0700 #ifdef CONFIG_FIQ
0701 init_FIQ(FIQ_START);
0702 #endif
0703
0704 s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2410base[0], NULL,
0705 0x4a000000);
0706 if (IS_ERR(s3c_intc[0])) {
0707 pr_err("irq: could not create main interrupt controller\n");
0708 return;
0709 }
0710
0711 s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2410subint[0],
0712 s3c_intc[0], 0x4a000018);
0713 s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
0714 }
0715 #endif
0716
0717 #ifdef CONFIG_CPU_S3C2412
0718 static struct s3c_irq_data init_s3c2412base[32] = {
0719 { .type = S3C_IRQTYPE_LEVEL, },
0720 { .type = S3C_IRQTYPE_LEVEL, },
0721 { .type = S3C_IRQTYPE_LEVEL, },
0722 { .type = S3C_IRQTYPE_LEVEL, },
0723 { .type = S3C_IRQTYPE_LEVEL, },
0724 { .type = S3C_IRQTYPE_LEVEL, },
0725 { .type = S3C_IRQTYPE_NONE, },
0726 { .type = S3C_IRQTYPE_EDGE, },
0727 { .type = S3C_IRQTYPE_EDGE, },
0728 { .type = S3C_IRQTYPE_EDGE, },
0729 { .type = S3C_IRQTYPE_EDGE, },
0730 { .type = S3C_IRQTYPE_EDGE, },
0731 { .type = S3C_IRQTYPE_EDGE, },
0732 { .type = S3C_IRQTYPE_EDGE, },
0733 { .type = S3C_IRQTYPE_EDGE, },
0734 { .type = S3C_IRQTYPE_LEVEL, },
0735 { .type = S3C_IRQTYPE_EDGE, },
0736 { .type = S3C_IRQTYPE_EDGE, },
0737 { .type = S3C_IRQTYPE_EDGE, },
0738 { .type = S3C_IRQTYPE_EDGE, },
0739 { .type = S3C_IRQTYPE_EDGE, },
0740 { .type = S3C_IRQTYPE_LEVEL, },
0741 { .type = S3C_IRQTYPE_EDGE, },
0742 { .type = S3C_IRQTYPE_LEVEL, },
0743 { .type = S3C_IRQTYPE_NONE, },
0744 { .type = S3C_IRQTYPE_EDGE, },
0745 { .type = S3C_IRQTYPE_EDGE, },
0746 { .type = S3C_IRQTYPE_EDGE, },
0747 { .type = S3C_IRQTYPE_LEVEL, },
0748 { .type = S3C_IRQTYPE_EDGE, },
0749 { .type = S3C_IRQTYPE_EDGE, },
0750 { .type = S3C_IRQTYPE_LEVEL, },
0751 };
0752
0753 static struct s3c_irq_data init_s3c2412eint[32] = {
0754 { .type = S3C_IRQTYPE_EINT, .parent_irq = 0 },
0755 { .type = S3C_IRQTYPE_EINT, .parent_irq = 1 },
0756 { .type = S3C_IRQTYPE_EINT, .parent_irq = 2 },
0757 { .type = S3C_IRQTYPE_EINT, .parent_irq = 3 },
0758 { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 },
0759 { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 },
0760 { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 },
0761 { .type = S3C_IRQTYPE_EINT, .parent_irq = 4 },
0762 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0763 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0764 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0765 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0766 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0767 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0768 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0769 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0770 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0771 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0772 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0773 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0774 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0775 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0776 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0777 { .type = S3C_IRQTYPE_EINT, .parent_irq = 5 },
0778 };
0779
0780 static struct s3c_irq_data init_s3c2412subint[32] = {
0781 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0782 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0783 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0784 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0785 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0786 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0787 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0788 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0789 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0790 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
0791 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
0792 { .type = S3C_IRQTYPE_NONE, },
0793 { .type = S3C_IRQTYPE_NONE, },
0794 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 },
0795 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 21 },
0796 };
0797
0798 void __init s3c2412_init_irq(void)
0799 {
0800 pr_info("S3C2412: IRQ Support\n");
0801
0802 #ifdef CONFIG_FIQ
0803 init_FIQ(FIQ_START);
0804 #endif
0805
0806 s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2412base[0], NULL,
0807 0x4a000000);
0808 if (IS_ERR(s3c_intc[0])) {
0809 pr_err("irq: could not create main interrupt controller\n");
0810 return;
0811 }
0812
0813 s3c24xx_init_intc(NULL, &init_s3c2412eint[0], s3c_intc[0], 0x560000a4);
0814 s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2412subint[0],
0815 s3c_intc[0], 0x4a000018);
0816 }
0817 #endif
0818
0819 #ifdef CONFIG_CPU_S3C2416
0820 static struct s3c_irq_data init_s3c2416base[32] = {
0821 { .type = S3C_IRQTYPE_EINT, },
0822 { .type = S3C_IRQTYPE_EINT, },
0823 { .type = S3C_IRQTYPE_EINT, },
0824 { .type = S3C_IRQTYPE_EINT, },
0825 { .type = S3C_IRQTYPE_LEVEL, },
0826 { .type = S3C_IRQTYPE_LEVEL, },
0827 { .type = S3C_IRQTYPE_NONE, },
0828 { .type = S3C_IRQTYPE_EDGE, },
0829 { .type = S3C_IRQTYPE_EDGE, },
0830 { .type = S3C_IRQTYPE_LEVEL, },
0831 { .type = S3C_IRQTYPE_EDGE, },
0832 { .type = S3C_IRQTYPE_EDGE, },
0833 { .type = S3C_IRQTYPE_EDGE, },
0834 { .type = S3C_IRQTYPE_EDGE, },
0835 { .type = S3C_IRQTYPE_EDGE, },
0836 { .type = S3C_IRQTYPE_LEVEL, },
0837 { .type = S3C_IRQTYPE_LEVEL, },
0838 { .type = S3C_IRQTYPE_LEVEL, },
0839 { .type = S3C_IRQTYPE_LEVEL, },
0840 { .type = S3C_IRQTYPE_NONE, },
0841 { .type = S3C_IRQTYPE_EDGE, },
0842 { .type = S3C_IRQTYPE_EDGE, },
0843 { .type = S3C_IRQTYPE_EDGE, },
0844 { .type = S3C_IRQTYPE_LEVEL, },
0845 { .type = S3C_IRQTYPE_EDGE, },
0846 { .type = S3C_IRQTYPE_EDGE, },
0847 { .type = S3C_IRQTYPE_EDGE, },
0848 { .type = S3C_IRQTYPE_EDGE, },
0849 { .type = S3C_IRQTYPE_LEVEL, },
0850 { .type = S3C_IRQTYPE_NONE, },
0851 { .type = S3C_IRQTYPE_EDGE, },
0852 { .type = S3C_IRQTYPE_LEVEL, },
0853 };
0854
0855 static struct s3c_irq_data init_s3c2416subint[32] = {
0856 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0857 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0858 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0859 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0860 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0861 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0862 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0863 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0864 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0865 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
0866 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
0867 { .type = S3C_IRQTYPE_NONE },
0868 { .type = S3C_IRQTYPE_NONE },
0869 { .type = S3C_IRQTYPE_NONE },
0870 { .type = S3C_IRQTYPE_NONE },
0871 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 },
0872 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 },
0873 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 },
0874 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
0875 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
0876 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
0877 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
0878 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
0879 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
0880 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 },
0881 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 },
0882 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 },
0883 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 },
0884 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 },
0885 };
0886
0887 static struct s3c_irq_data init_s3c2416_second[32] = {
0888 { .type = S3C_IRQTYPE_EDGE },
0889 { .type = S3C_IRQTYPE_NONE },
0890 { .type = S3C_IRQTYPE_NONE },
0891 { .type = S3C_IRQTYPE_NONE },
0892 { .type = S3C_IRQTYPE_EDGE },
0893 { .type = S3C_IRQTYPE_NONE },
0894 { .type = S3C_IRQTYPE_EDGE },
0895 };
0896
0897 void __init s3c2416_init_irq(void)
0898 {
0899 pr_info("S3C2416: IRQ Support\n");
0900
0901 #ifdef CONFIG_FIQ
0902 init_FIQ(FIQ_START);
0903 #endif
0904
0905 s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2416base[0], NULL,
0906 0x4a000000);
0907 if (IS_ERR(s3c_intc[0])) {
0908 pr_err("irq: could not create main interrupt controller\n");
0909 return;
0910 }
0911
0912 s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
0913 s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2416subint[0],
0914 s3c_intc[0], 0x4a000018);
0915
0916 s3c_intc[2] = s3c24xx_init_intc(NULL, &init_s3c2416_second[0],
0917 NULL, 0x4a000040);
0918 }
0919
0920 #endif
0921
0922 #ifdef CONFIG_CPU_S3C2440
0923 static struct s3c_irq_data init_s3c2440base[32] = {
0924 { .type = S3C_IRQTYPE_EINT, },
0925 { .type = S3C_IRQTYPE_EINT, },
0926 { .type = S3C_IRQTYPE_EINT, },
0927 { .type = S3C_IRQTYPE_EINT, },
0928 { .type = S3C_IRQTYPE_LEVEL, },
0929 { .type = S3C_IRQTYPE_LEVEL, },
0930 { .type = S3C_IRQTYPE_LEVEL, },
0931 { .type = S3C_IRQTYPE_EDGE, },
0932 { .type = S3C_IRQTYPE_EDGE, },
0933 { .type = S3C_IRQTYPE_LEVEL, },
0934 { .type = S3C_IRQTYPE_EDGE, },
0935 { .type = S3C_IRQTYPE_EDGE, },
0936 { .type = S3C_IRQTYPE_EDGE, },
0937 { .type = S3C_IRQTYPE_EDGE, },
0938 { .type = S3C_IRQTYPE_EDGE, },
0939 { .type = S3C_IRQTYPE_LEVEL, },
0940 { .type = S3C_IRQTYPE_EDGE, },
0941 { .type = S3C_IRQTYPE_EDGE, },
0942 { .type = S3C_IRQTYPE_EDGE, },
0943 { .type = S3C_IRQTYPE_EDGE, },
0944 { .type = S3C_IRQTYPE_EDGE, },
0945 { .type = S3C_IRQTYPE_EDGE, },
0946 { .type = S3C_IRQTYPE_EDGE, },
0947 { .type = S3C_IRQTYPE_LEVEL, },
0948 { .type = S3C_IRQTYPE_LEVEL, },
0949 { .type = S3C_IRQTYPE_EDGE, },
0950 { .type = S3C_IRQTYPE_EDGE, },
0951 { .type = S3C_IRQTYPE_EDGE, },
0952 { .type = S3C_IRQTYPE_LEVEL, },
0953 { .type = S3C_IRQTYPE_EDGE, },
0954 { .type = S3C_IRQTYPE_EDGE, },
0955 { .type = S3C_IRQTYPE_LEVEL, },
0956 };
0957
0958 static struct s3c_irq_data init_s3c2440subint[32] = {
0959 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0960 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0961 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
0962 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0963 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0964 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
0965 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0966 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0967 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
0968 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
0969 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
0970 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 },
0971 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 },
0972 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 },
0973 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 },
0974 };
0975
0976 void __init s3c2440_init_irq(void)
0977 {
0978 pr_info("S3C2440: IRQ Support\n");
0979
0980 #ifdef CONFIG_FIQ
0981 init_FIQ(FIQ_START);
0982 #endif
0983
0984 s3c_intc[0] = s3c24xx_init_intc(NULL, &init_s3c2440base[0], NULL,
0985 0x4a000000);
0986 if (IS_ERR(s3c_intc[0])) {
0987 pr_err("irq: could not create main interrupt controller\n");
0988 return;
0989 }
0990
0991 s3c24xx_init_intc(NULL, &init_eint[0], s3c_intc[0], 0x560000a4);
0992 s3c_intc[1] = s3c24xx_init_intc(NULL, &init_s3c2440subint[0],
0993 s3c_intc[0], 0x4a000018);
0994 }
0995 #endif
0996
0997 #ifdef CONFIG_CPU_S3C2442
0998 static struct s3c_irq_data init_s3c2442base[32] = {
0999 { .type = S3C_IRQTYPE_EINT, },
1000 { .type = S3C_IRQTYPE_EINT, },
1001 { .type = S3C_IRQTYPE_EINT, },
1002 { .type = S3C_IRQTYPE_EINT, },
1003 { .type = S3C_IRQTYPE_LEVEL, },
1004 { .type = S3C_IRQTYPE_LEVEL, },
1005 { .type = S3C_IRQTYPE_LEVEL, },
1006 { .type = S3C_IRQTYPE_EDGE, },
1007 { .type = S3C_IRQTYPE_EDGE, },
1008 { .type = S3C_IRQTYPE_EDGE, },
1009 { .type = S3C_IRQTYPE_EDGE, },
1010 { .type = S3C_IRQTYPE_EDGE, },
1011 { .type = S3C_IRQTYPE_EDGE, },
1012 { .type = S3C_IRQTYPE_EDGE, },
1013 { .type = S3C_IRQTYPE_EDGE, },
1014 { .type = S3C_IRQTYPE_LEVEL, },
1015 { .type = S3C_IRQTYPE_EDGE, },
1016 { .type = S3C_IRQTYPE_EDGE, },
1017 { .type = S3C_IRQTYPE_EDGE, },
1018 { .type = S3C_IRQTYPE_EDGE, },
1019 { .type = S3C_IRQTYPE_EDGE, },
1020 { .type = S3C_IRQTYPE_EDGE, },
1021 { .type = S3C_IRQTYPE_EDGE, },
1022 { .type = S3C_IRQTYPE_LEVEL, },
1023 { .type = S3C_IRQTYPE_LEVEL, },
1024 { .type = S3C_IRQTYPE_EDGE, },
1025 { .type = S3C_IRQTYPE_EDGE, },
1026 { .type = S3C_IRQTYPE_EDGE, },
1027 { .type = S3C_IRQTYPE_LEVEL, },
1028 { .type = S3C_IRQTYPE_EDGE, },
1029 { .type = S3C_IRQTYPE_EDGE, },
1030 { .type = S3C_IRQTYPE_LEVEL, },
1031 };
1032
1033 static struct s3c_irq_data init_s3c2442subint[32] = {
1034 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
1035 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
1036 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
1037 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
1038 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
1039 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
1040 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
1041 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
1042 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
1043 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
1044 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
1045 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 },
1046 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 },
1047 };
1048
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, },
1073 { .type = S3C_IRQTYPE_EINT, },
1074 { .type = S3C_IRQTYPE_EINT, },
1075 { .type = S3C_IRQTYPE_EINT, },
1076 { .type = S3C_IRQTYPE_LEVEL, },
1077 { .type = S3C_IRQTYPE_LEVEL, },
1078 { .type = S3C_IRQTYPE_LEVEL, },
1079 { .type = S3C_IRQTYPE_EDGE, },
1080 { .type = S3C_IRQTYPE_EDGE, },
1081 { .type = S3C_IRQTYPE_LEVEL, },
1082 { .type = S3C_IRQTYPE_EDGE, },
1083 { .type = S3C_IRQTYPE_EDGE, },
1084 { .type = S3C_IRQTYPE_EDGE, },
1085 { .type = S3C_IRQTYPE_EDGE, },
1086 { .type = S3C_IRQTYPE_EDGE, },
1087 { .type = S3C_IRQTYPE_LEVEL, },
1088 { .type = S3C_IRQTYPE_LEVEL, },
1089 { .type = S3C_IRQTYPE_LEVEL, },
1090 { .type = S3C_IRQTYPE_LEVEL, },
1091 { .type = S3C_IRQTYPE_EDGE, },
1092 { .type = S3C_IRQTYPE_EDGE, },
1093 { .type = S3C_IRQTYPE_EDGE, },
1094 { .type = S3C_IRQTYPE_EDGE, },
1095 { .type = S3C_IRQTYPE_LEVEL, },
1096 { .type = S3C_IRQTYPE_EDGE, },
1097 { .type = S3C_IRQTYPE_EDGE, },
1098 { .type = S3C_IRQTYPE_EDGE, },
1099 { .type = S3C_IRQTYPE_EDGE, },
1100 { .type = S3C_IRQTYPE_LEVEL, },
1101 { .type = S3C_IRQTYPE_EDGE, },
1102 { .type = S3C_IRQTYPE_EDGE, },
1103 { .type = S3C_IRQTYPE_LEVEL, },
1104 };
1105
1106
1107 static struct s3c_irq_data init_s3c2443subint[32] = {
1108 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
1109 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
1110 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 28 },
1111 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
1112 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
1113 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 23 },
1114 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
1115 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
1116 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 15 },
1117 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
1118 { .type = S3C_IRQTYPE_EDGE, .parent_irq = 31 },
1119 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 },
1120 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 6 },
1121 { .type = S3C_IRQTYPE_NONE },
1122 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 },
1123 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 },
1124 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 },
1125 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 16 },
1126 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
1127 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
1128 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
1129 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
1130 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
1131 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 17 },
1132 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 },
1133 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 },
1134 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 18 },
1135 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 },
1136 { .type = S3C_IRQTYPE_LEVEL, .parent_irq = 9 },
1137 };
1138
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
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
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
1186
1187
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
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
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
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
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