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