1/* linux/arch/arm/plat-s3c24xx/irq.c 2 * 3 * Copyright (c) 2003,2004 Simtec Electronics 4 * Ben Dooks <ben@simtec.co.uk> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 * Changelog: 21 * 22 * 22-Jul-2004 Ben Dooks <ben@simtec.co.uk> 23 * Fixed compile warnings 24 * 25 * 22-Jul-2004 Roc Wu <cooloney@yahoo.com.cn> 26 * Fixed s3c_extirq_type 27 * 28 * 21-Jul-2004 Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org> 29 * Addition of ADC/TC demux 30 * 31 * 04-Oct-2004 Klaus Fetscher <k.fetscher@fetron.de> 32 * Fix for set_irq_type() on low EINT numbers 33 * 34 * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk> 35 * Tidy up KF's patch and sort out new release 36 * 37 * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk> 38 * Add support for power management controls 39 * 40 * 04-Nov-2004 Ben Dooks 41 * Fix standard IRQ wake for EINT0..4 and RTC 42 * 43 * 22-Feb-2005 Ben Dooks 44 * Fixed edge-triggering on ADC IRQ 45 * 46 * 28-Jun-2005 Ben Dooks 47 * Mark IRQ_LCD valid 48 * 49 * 25-Jul-2005 Ben Dooks 50 * Split the S3C2440 IRQ code to seperate file 51*/ 52 53#include <linux/init.h> 54#include <linux/module.h> 55#include <linux/interrupt.h> 56#include <linux/ioport.h> 57#include <linux/sysdev.h> 58 59#include <asm/hardware.h> 60#include <asm/irq.h> 61#include <asm/io.h> 62 63#include <asm/mach/irq.h> 64 65#include <asm/arch/regs-irq.h> 66#include <asm/arch/regs-gpio.h> 67 68#include <asm/plat-s3c24xx/cpu.h> 69#include <asm/plat-s3c24xx/pm.h> 70#include <asm/plat-s3c24xx/irq.h> 71 72/* wakeup irq control */ 73 74#ifdef CONFIG_PM 75 76/* state for IRQs over sleep */ 77 78/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources 79 * 80 * set bit to 1 in allow bitfield to enable the wakeup settings on it 81*/ 82 83unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL; 84unsigned long s3c_irqwake_intmask = 0xffffffffL; 85unsigned long s3c_irqwake_eintallow = 0x0000fff0L; 86unsigned long s3c_irqwake_eintmask = 0xffffffffL; 87 88int 89s3c_irq_wake(unsigned int irqno, unsigned int state) 90{ 91 unsigned long irqbit = 1 << (irqno - IRQ_EINT0); 92 93 if (!(s3c_irqwake_intallow & irqbit)) 94 return -ENOENT; 95 96 printk(KERN_INFO "wake %s for irq %d\n", 97 state ? "enabled" : "disabled", irqno); 98 99 if (!state) 100 s3c_irqwake_intmask |= irqbit; 101 else 102 s3c_irqwake_intmask &= ~irqbit; 103 104 return 0; 105} 106 107static int 108s3c_irqext_wake(unsigned int irqno, unsigned int state) 109{ 110 unsigned long bit = 1L << (irqno - EXTINT_OFF); 111 112 if (!(s3c_irqwake_eintallow & bit)) 113 return -ENOENT; 114 115 printk(KERN_INFO "wake %s for irq %d\n", 116 state ? "enabled" : "disabled", irqno); 117 118 if (!state) 119 s3c_irqwake_eintmask |= bit; 120 else 121 s3c_irqwake_eintmask &= ~bit; 122 123 return 0; 124} 125 126#else 127#define s3c_irqext_wake NULL 128#define s3c_irq_wake NULL 129#endif 130 131 132static void 133s3c_irq_mask(unsigned int irqno) 134{ 135 unsigned long mask; 136 137 irqno -= IRQ_EINT0; 138 139 mask = __raw_readl(S3C2410_INTMSK); 140 mask |= 1UL << irqno; 141 __raw_writel(mask, S3C2410_INTMSK); 142} 143 144static inline void 145s3c_irq_ack(unsigned int irqno) 146{ 147 unsigned long bitval = 1UL << (irqno - IRQ_EINT0); 148 149 __raw_writel(bitval, S3C2410_SRCPND); 150 __raw_writel(bitval, S3C2410_INTPND); 151} 152 153static inline void 154s3c_irq_maskack(unsigned int irqno) 155{ 156 unsigned long bitval = 1UL << (irqno - IRQ_EINT0); 157 unsigned long mask; 158 159 mask = __raw_readl(S3C2410_INTMSK); 160 __raw_writel(mask|bitval, S3C2410_INTMSK); 161 162 __raw_writel(bitval, S3C2410_SRCPND); 163 __raw_writel(bitval, S3C2410_INTPND); 164} 165 166 167static void 168s3c_irq_unmask(unsigned int irqno) 169{ 170 unsigned long mask; 171 172 if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23) 173 irqdbf2("s3c_irq_unmask %d\n", irqno); 174 175 irqno -= IRQ_EINT0; 176 177 mask = __raw_readl(S3C2410_INTMSK); 178 mask &= ~(1UL << irqno); 179 __raw_writel(mask, S3C2410_INTMSK); 180} 181 182struct irq_chip s3c_irq_level_chip = { 183 .name = "s3c-level", 184 .ack = s3c_irq_maskack, 185 .mask = s3c_irq_mask, 186 .unmask = s3c_irq_unmask, 187 .set_wake = s3c_irq_wake 188}; 189 190static struct irq_chip s3c_irq_chip = { 191 .name = "s3c", 192 .ack = s3c_irq_ack, 193 .mask = s3c_irq_mask, 194 .unmask = s3c_irq_unmask, 195 .set_wake = s3c_irq_wake 196}; 197 198static void 199s3c_irqext_mask(unsigned int irqno) 200{ 201 unsigned long mask; 202 203 irqno -= EXTINT_OFF; 204 205 mask = __raw_readl(S3C24XX_EINTMASK); 206 mask |= ( 1UL << irqno); 207 __raw_writel(mask, S3C24XX_EINTMASK); 208} 209 210static void 211s3c_irqext_ack(unsigned int irqno) 212{ 213 unsigned long req; 214 unsigned long bit; 215 unsigned long mask; 216 217 bit = 1UL << (irqno - EXTINT_OFF); 218 219 mask = __raw_readl(S3C24XX_EINTMASK); 220 221 __raw_writel(bit, S3C24XX_EINTPEND); 222 223 req = __raw_readl(S3C24XX_EINTPEND); 224 req &= ~mask; 225 226 /* not sure if we should be acking the parent irq... */ 227 228 if (irqno <= IRQ_EINT7 ) { 229 if ((req & 0xf0) == 0) 230 s3c_irq_ack(IRQ_EINT4t7); 231 } else { 232 if ((req >> 8) == 0) 233 s3c_irq_ack(IRQ_EINT8t23); 234 } 235} 236 237static void 238s3c_irqext_unmask(unsigned int irqno) 239{ 240 unsigned long mask; 241 242 irqno -= EXTINT_OFF; 243 244 mask = __raw_readl(S3C24XX_EINTMASK); 245 mask &= ~( 1UL << irqno); 246 __raw_writel(mask, S3C24XX_EINTMASK); 247} 248 249int 250s3c_irqext_type(unsigned int irq, unsigned int type) 251{ 252 void __iomem *extint_reg; 253 void __iomem *gpcon_reg; 254 unsigned long gpcon_offset, extint_offset; 255 unsigned long newvalue = 0, value; 256 257 if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3)) 258 { 259 gpcon_reg = S3C2410_GPFCON; 260 extint_reg = S3C24XX_EXTINT0; 261 gpcon_offset = (irq - IRQ_EINT0) * 2; 262 extint_offset = (irq - IRQ_EINT0) * 4; 263 } 264 else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7)) 265 { 266 gpcon_reg = S3C2410_GPFCON; 267 extint_reg = S3C24XX_EXTINT0; 268 gpcon_offset = (irq - (EXTINT_OFF)) * 2; 269 extint_offset = (irq - (EXTINT_OFF)) * 4; 270 } 271 else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15)) 272 { 273 gpcon_reg = S3C2410_GPGCON; 274 extint_reg = S3C24XX_EXTINT1; 275 gpcon_offset = (irq - IRQ_EINT8) * 2; 276 extint_offset = (irq - IRQ_EINT8) * 4; 277 } 278 else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23)) 279 { 280 gpcon_reg = S3C2410_GPGCON; 281 extint_reg = S3C24XX_EXTINT2; 282 gpcon_offset = (irq - IRQ_EINT8) * 2; 283 extint_offset = (irq - IRQ_EINT16) * 4; 284 } else 285 return -1; 286 287 /* Set the GPIO to external interrupt mode */ 288 value = __raw_readl(gpcon_reg); 289 value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset); 290 __raw_writel(value, gpcon_reg); 291 292 /* Set the external interrupt to pointed trigger type */ 293 switch (type) 294 { 295 case IRQT_NOEDGE: 296 printk(KERN_WARNING "No edge setting!\n"); 297 break; 298 299 case IRQT_RISING: 300 newvalue = S3C2410_EXTINT_RISEEDGE; 301 break; 302 303 case IRQT_FALLING: 304 newvalue = S3C2410_EXTINT_FALLEDGE; 305 break; 306 307 case IRQT_BOTHEDGE: 308 newvalue = S3C2410_EXTINT_BOTHEDGE; 309 break; 310 311 case IRQT_LOW: 312 newvalue = S3C2410_EXTINT_LOWLEV; 313 break; 314 315 case IRQT_HIGH: 316 newvalue = S3C2410_EXTINT_HILEV; 317 break; 318 319 default: 320 printk(KERN_ERR "No such irq type %d", type); 321 return -1; 322 } 323 324 value = __raw_readl(extint_reg); 325 value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset); 326 __raw_writel(value, extint_reg); 327 328 return 0; 329} 330 331static struct irq_chip s3c_irqext_chip = { 332 .name = "s3c-ext", 333 .mask = s3c_irqext_mask, 334 .unmask = s3c_irqext_unmask, 335 .ack = s3c_irqext_ack, 336 .set_type = s3c_irqext_type, 337 .set_wake = s3c_irqext_wake 338}; 339 340static struct irq_chip s3c_irq_eint0t4 = { 341 .name = "s3c-ext0", 342 .ack = s3c_irq_ack, 343 .mask = s3c_irq_mask, 344 .unmask = s3c_irq_unmask, 345 .set_wake = s3c_irq_wake, 346 .set_type = s3c_irqext_type, 347}; 348 349/* mask values for the parent registers for each of the interrupt types */ 350 351#define INTMSK_UART0 (1UL << (IRQ_UART0 - IRQ_EINT0)) 352#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0)) 353#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) 354#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) 355 356 357/* UART0 */ 358 359static void 360s3c_irq_uart0_mask(unsigned int irqno) 361{ 362 s3c_irqsub_mask(irqno, INTMSK_UART0, 7); 363} 364 365static void 366s3c_irq_uart0_unmask(unsigned int irqno) 367{ 368 s3c_irqsub_unmask(irqno, INTMSK_UART0); 369} 370 371static void 372s3c_irq_uart0_ack(unsigned int irqno) 373{ 374 s3c_irqsub_maskack(irqno, INTMSK_UART0, 7); 375} 376 377static struct irq_chip s3c_irq_uart0 = { 378 .name = "s3c-uart0", 379 .mask = s3c_irq_uart0_mask, 380 .unmask = s3c_irq_uart0_unmask, 381 .ack = s3c_irq_uart0_ack, 382}; 383 384/* UART1 */ 385 386static void 387s3c_irq_uart1_mask(unsigned int irqno) 388{ 389 s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3); 390} 391 392static void 393s3c_irq_uart1_unmask(unsigned int irqno) 394{ 395 s3c_irqsub_unmask(irqno, INTMSK_UART1); 396} 397 398static void 399s3c_irq_uart1_ack(unsigned int irqno) 400{ 401 s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3); 402} 403 404static struct irq_chip s3c_irq_uart1 = { 405 .name = "s3c-uart1", 406 .mask = s3c_irq_uart1_mask, 407 .unmask = s3c_irq_uart1_unmask, 408 .ack = s3c_irq_uart1_ack, 409}; 410 411/* UART2 */ 412 413static void 414s3c_irq_uart2_mask(unsigned int irqno) 415{ 416 s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6); 417} 418 419static void 420s3c_irq_uart2_unmask(unsigned int irqno) 421{ 422 s3c_irqsub_unmask(irqno, INTMSK_UART2); 423} 424 425static void 426s3c_irq_uart2_ack(unsigned int irqno) 427{ 428 s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6); 429} 430 431static struct irq_chip s3c_irq_uart2 = { 432 .name = "s3c-uart2", 433 .mask = s3c_irq_uart2_mask, 434 .unmask = s3c_irq_uart2_unmask, 435 .ack = s3c_irq_uart2_ack, 436}; 437 438/* ADC and Touchscreen */ 439 440static void 441s3c_irq_adc_mask(unsigned int irqno) 442{ 443 s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9); 444} 445 446static void 447s3c_irq_adc_unmask(unsigned int irqno) 448{ 449 s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT); 450} 451 452static void 453s3c_irq_adc_ack(unsigned int irqno) 454{ 455 s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9); 456} 457 458static struct irq_chip s3c_irq_adc = { 459 .name = "s3c-adc", 460 .mask = s3c_irq_adc_mask, 461 .unmask = s3c_irq_adc_unmask, 462 .ack = s3c_irq_adc_ack, 463}; 464 465/* irq demux for adc */ 466static void s3c_irq_demux_adc(unsigned int irq, 467 struct irq_desc *desc) 468{ 469 unsigned int subsrc, submsk; 470 unsigned int offset = 9; 471 struct irq_desc *mydesc; 472 473 /* read the current pending interrupts, and the mask 474 * for what it is available */ 475 476 subsrc = __raw_readl(S3C2410_SUBSRCPND); 477 submsk = __raw_readl(S3C2410_INTSUBMSK); 478 479 subsrc &= ~submsk; 480 subsrc >>= offset; 481 subsrc &= 3; 482 483 if (subsrc != 0) { 484 if (subsrc & 1) { 485 mydesc = irq_desc + IRQ_TC; 486 desc_handle_irq(IRQ_TC, mydesc); 487 } 488 if (subsrc & 2) { 489 mydesc = irq_desc + IRQ_ADC; 490 desc_handle_irq(IRQ_ADC, mydesc); 491 } 492 } 493} 494 495static void s3c_irq_demux_uart(unsigned int start) 496{ 497 unsigned int subsrc, submsk; 498 unsigned int offset = start - IRQ_S3CUART_RX0; 499 struct irq_desc *desc; 500 501 /* read the current pending interrupts, and the mask 502 * for what it is available */ 503 504 subsrc = __raw_readl(S3C2410_SUBSRCPND); 505 submsk = __raw_readl(S3C2410_INTSUBMSK); 506 507 irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n", 508 start, offset, subsrc, submsk); 509 510 subsrc &= ~submsk; 511 subsrc >>= offset; 512 subsrc &= 7; 513 514 if (subsrc != 0) { 515 desc = irq_desc + start; 516 517 if (subsrc & 1) 518 desc_handle_irq(start, desc); 519 520 desc++; 521 522 if (subsrc & 2) 523 desc_handle_irq(start+1, desc); 524 525 desc++; 526 527 if (subsrc & 4) 528 desc_handle_irq(start+2, desc); 529 } 530} 531 532/* uart demux entry points */ 533 534static void 535s3c_irq_demux_uart0(unsigned int irq, 536 struct irq_desc *desc) 537{ 538 irq = irq; 539 s3c_irq_demux_uart(IRQ_S3CUART_RX0); 540} 541 542static void 543s3c_irq_demux_uart1(unsigned int irq, 544 struct irq_desc *desc) 545{ 546 irq = irq; 547 s3c_irq_demux_uart(IRQ_S3CUART_RX1); 548} 549 550static void 551s3c_irq_demux_uart2(unsigned int irq, 552 struct irq_desc *desc) 553{ 554 irq = irq; 555 s3c_irq_demux_uart(IRQ_S3CUART_RX2); 556} 557 558static void 559s3c_irq_demux_extint8(unsigned int irq, 560 struct irq_desc *desc) 561{ 562 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); 563 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); 564 565 eintpnd &= ~eintmsk; 566 eintpnd &= ~0xff; /* ignore lower irqs */ 567 568 /* we may as well handle all the pending IRQs here */ 569 570 while (eintpnd) { 571 irq = __ffs(eintpnd); 572 eintpnd &= ~(1<<irq); 573 574 irq += (IRQ_EINT4 - 4); 575 desc_handle_irq(irq, irq_desc + irq); 576 } 577 578} 579 580static void 581s3c_irq_demux_extint4t7(unsigned int irq, 582 struct irq_desc *desc) 583{ 584 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); 585 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); 586 587 eintpnd &= ~eintmsk; 588 eintpnd &= 0xff; /* only lower irqs */ 589 590 /* we may as well handle all the pending IRQs here */ 591 592 while (eintpnd) { 593 irq = __ffs(eintpnd); 594 eintpnd &= ~(1<<irq); 595 596 irq += (IRQ_EINT4 - 4); 597 598 desc_handle_irq(irq, irq_desc + irq); 599 } 600} 601 602#ifdef CONFIG_PM 603 604static struct sleep_save irq_save[] = { 605 SAVE_ITEM(S3C2410_INTMSK), 606 SAVE_ITEM(S3C2410_INTSUBMSK), 607}; 608 609/* the extint values move between the s3c2410/s3c2440 and the s3c2412 610 * so we use an array to hold them, and to calculate the address of 611 * the register at run-time 612*/ 613 614static unsigned long save_extint[3]; 615static unsigned long save_eintflt[4]; 616static unsigned long save_eintmask; 617 618int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state) 619{ 620 unsigned int i; 621 622 for (i = 0; i < ARRAY_SIZE(save_extint); i++) 623 save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4)); 624 625 for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) 626 save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4)); 627 628 s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); 629 save_eintmask = __raw_readl(S3C24XX_EINTMASK); 630 631 return 0; 632} 633 634int s3c24xx_irq_resume(struct sys_device *dev) 635{ 636 unsigned int i; 637 638 for (i = 0; i < ARRAY_SIZE(save_extint); i++) 639 __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4)); 640 641 for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) 642 __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4)); 643 644 s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); 645 __raw_writel(save_eintmask, S3C24XX_EINTMASK); 646 647 return 0; 648} 649 650#else 651#define s3c24xx_irq_suspend NULL 652#define s3c24xx_irq_resume NULL 653#endif 654 655/* s3c24xx_init_irq 656 * 657 * Initialise S3C2410 IRQ system 658*/ 659 660void __init s3c24xx_init_irq(void) 661{ 662 unsigned long pend; 663 unsigned long last; 664 int irqno; 665 int i; 666 667 irqdbf("s3c2410_init_irq: clearing interrupt status flags\n"); 668 669 /* first, clear all interrupts pending... */ 670 671 last = 0; 672 for (i = 0; i < 4; i++) { 673 pend = __raw_readl(S3C24XX_EINTPEND); 674 675 if (pend == 0 || pend == last) 676 break; 677 678 __raw_writel(pend, S3C24XX_EINTPEND); 679 printk("irq: clearing pending ext status %08x\n", (int)pend); 680 last = pend; 681 } 682 683 last = 0; 684 for (i = 0; i < 4; i++) { 685 pend = __raw_readl(S3C2410_INTPND); 686 687 if (pend == 0 || pend == last) 688 break; 689 690 __raw_writel(pend, S3C2410_SRCPND); 691 __raw_writel(pend, S3C2410_INTPND); 692 printk("irq: clearing pending status %08x\n", (int)pend); 693 last = pend; 694 } 695 696 last = 0; 697 for (i = 0; i < 4; i++) { 698 pend = __raw_readl(S3C2410_SUBSRCPND); 699 700 if (pend == 0 || pend == last) 701 break; 702 703 printk("irq: clearing subpending status %08x\n", (int)pend); 704 __raw_writel(pend, S3C2410_SUBSRCPND); 705 last = pend; 706 } 707 708 /* register the main interrupts */ 709 710 irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n"); 711 712 for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) { 713 /* set all the s3c2410 internal irqs */ 714 715 switch (irqno) { 716 /* deal with the special IRQs (cascaded) */ 717 718 case IRQ_EINT4t7: 719 case IRQ_EINT8t23: 720 case IRQ_UART0: 721 case IRQ_UART1: 722 case IRQ_UART2: 723 case IRQ_ADCPARENT: 724 set_irq_chip(irqno, &s3c_irq_level_chip); 725 set_irq_handler(irqno, handle_level_irq); 726 break; 727 728 case IRQ_RESERVED6: 729 case IRQ_RESERVED24: 730 /* no IRQ here */ 731 break; 732 733 default: 734 //irqdbf("registering irq %d (s3c irq)\n", irqno); 735 set_irq_chip(irqno, &s3c_irq_chip); 736 set_irq_handler(irqno, handle_edge_irq); 737 set_irq_flags(irqno, IRQF_VALID); 738 } 739 } 740 741 /* setup the cascade irq handlers */ 742 743 set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7); 744 set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8); 745 746 set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); 747 set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); 748 set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2); 749 set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc); 750 751 /* external interrupts */ 752 753 for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { 754 irqdbf("registering irq %d (ext int)\n", irqno); 755 set_irq_chip(irqno, &s3c_irq_eint0t4); 756 set_irq_handler(irqno, handle_edge_irq); 757 set_irq_flags(irqno, IRQF_VALID); 758 } 759 760 for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) { 761 irqdbf("registering irq %d (extended s3c irq)\n", irqno); 762 set_irq_chip(irqno, &s3c_irqext_chip); 763 set_irq_handler(irqno, handle_edge_irq); 764 set_irq_flags(irqno, IRQF_VALID); 765 } 766 767 /* register the uart interrupts */ 768 769 irqdbf("s3c2410: registering external interrupts\n"); 770 771 for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) { 772 irqdbf("registering irq %d (s3c uart0 irq)\n", irqno); 773 set_irq_chip(irqno, &s3c_irq_uart0); 774 set_irq_handler(irqno, handle_level_irq); 775 set_irq_flags(irqno, IRQF_VALID); 776 } 777 778 for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) { 779 irqdbf("registering irq %d (s3c uart1 irq)\n", irqno); 780 set_irq_chip(irqno, &s3c_irq_uart1); 781 set_irq_handler(irqno, handle_level_irq); 782 set_irq_flags(irqno, IRQF_VALID); 783 } 784 785 for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) { 786 irqdbf("registering irq %d (s3c uart2 irq)\n", irqno); 787 set_irq_chip(irqno, &s3c_irq_uart2); 788 set_irq_handler(irqno, handle_level_irq); 789 set_irq_flags(irqno, IRQF_VALID); 790 } 791 792 for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) { 793 irqdbf("registering irq %d (s3c adc irq)\n", irqno); 794 set_irq_chip(irqno, &s3c_irq_adc); 795 set_irq_handler(irqno, handle_edge_irq); 796 set_irq_flags(irqno, IRQF_VALID); 797 } 798 799 irqdbf("s3c2410: registered interrupt handlers\n"); 800} 801