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