diff options
| -rw-r--r-- | arch/arm/mach-s3c2410/irq.c | 49 | ||||
| -rw-r--r-- | include/asm-arm/arch-s3c2410/entry-macro.S | 30 | ||||
| -rw-r--r-- | include/asm-arm/arch-s3c2410/regs-irq.h | 6 |
3 files changed, 46 insertions, 39 deletions
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 46465742ed79..6822dc7f7799 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c | |||
| @@ -191,13 +191,9 @@ static struct irqchip s3c_irq_chip = { | |||
| 191 | .ack = s3c_irq_ack, | 191 | .ack = s3c_irq_ack, |
| 192 | .mask = s3c_irq_mask, | 192 | .mask = s3c_irq_mask, |
| 193 | .unmask = s3c_irq_unmask, | 193 | .unmask = s3c_irq_unmask, |
| 194 | .set_wake = s3c_irq_wake | 194 | .set_wake = s3c_irq_wake |
| 195 | }; | 195 | }; |
| 196 | 196 | ||
| 197 | /* S3C2410_EINTMASK | ||
| 198 | * S3C2410_EINTPEND | ||
| 199 | */ | ||
| 200 | |||
| 201 | static void | 197 | static void |
| 202 | s3c_irqext_mask(unsigned int irqno) | 198 | s3c_irqext_mask(unsigned int irqno) |
| 203 | { | 199 | { |
| @@ -205,9 +201,9 @@ s3c_irqext_mask(unsigned int irqno) | |||
| 205 | 201 | ||
| 206 | irqno -= EXTINT_OFF; | 202 | irqno -= EXTINT_OFF; |
| 207 | 203 | ||
| 208 | mask = __raw_readl(S3C2410_EINTMASK); | 204 | mask = __raw_readl(S3C24XX_EINTMASK); |
| 209 | mask |= ( 1UL << irqno); | 205 | mask |= ( 1UL << irqno); |
| 210 | __raw_writel(mask, S3C2410_EINTMASK); | 206 | __raw_writel(mask, S3C24XX_EINTMASK); |
| 211 | 207 | ||
| 212 | if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) { | 208 | if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) { |
| 213 | /* check to see if all need masking */ | 209 | /* check to see if all need masking */ |
| @@ -232,11 +228,11 @@ s3c_irqext_ack(unsigned int irqno) | |||
| 232 | bit = 1UL << (irqno - EXTINT_OFF); | 228 | bit = 1UL << (irqno - EXTINT_OFF); |
| 233 | 229 | ||
| 234 | 230 | ||
| 235 | mask = __raw_readl(S3C2410_EINTMASK); | 231 | mask = __raw_readl(S3C24XX_EINTMASK); |
| 236 | 232 | ||
| 237 | __raw_writel(bit, S3C2410_EINTPEND); | 233 | __raw_writel(bit, S3C24XX_EINTPEND); |
| 238 | 234 | ||
| 239 | req = __raw_readl(S3C2410_EINTPEND); | 235 | req = __raw_readl(S3C24XX_EINTPEND); |
| 240 | req &= ~mask; | 236 | req &= ~mask; |
| 241 | 237 | ||
| 242 | /* not sure if we should be acking the parent irq... */ | 238 | /* not sure if we should be acking the parent irq... */ |
| @@ -257,9 +253,9 @@ s3c_irqext_unmask(unsigned int irqno) | |||
| 257 | 253 | ||
| 258 | irqno -= EXTINT_OFF; | 254 | irqno -= EXTINT_OFF; |
| 259 | 255 | ||
| 260 | mask = __raw_readl(S3C2410_EINTMASK); | 256 | mask = __raw_readl(S3C24XX_EINTMASK); |
| 261 | mask &= ~( 1UL << irqno); | 257 | mask &= ~( 1UL << irqno); |
| 262 | __raw_writel(mask, S3C2410_EINTMASK); | 258 | __raw_writel(mask, S3C24XX_EINTMASK); |
| 263 | 259 | ||
| 264 | s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23); | 260 | s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23); |
| 265 | } | 261 | } |
| @@ -572,6 +568,23 @@ s3c_irq_demux_uart2(unsigned int irq, | |||
| 572 | s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs); | 568 | s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs); |
| 573 | } | 569 | } |
| 574 | 570 | ||
| 571 | static void | ||
| 572 | s3c_irq_demux_extint(unsigned int irq, | ||
| 573 | struct irqdesc *desc, | ||
| 574 | struct pt_regs *regs) | ||
| 575 | { | ||
| 576 | unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); | ||
| 577 | unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); | ||
| 578 | |||
| 579 | eintpnd &= ~eintmsk; | ||
| 580 | |||
| 581 | if (eintpnd) { | ||
| 582 | irq = fls(eintpnd); | ||
| 583 | irq += (IRQ_EINT4 - (4 + 1)); | ||
| 584 | |||
| 585 | desc_handle_irq(irq, irq_desc + irq, regs); | ||
| 586 | } | ||
| 587 | } | ||
| 575 | 588 | ||
| 576 | /* s3c24xx_init_irq | 589 | /* s3c24xx_init_irq |
| 577 | * | 590 | * |
| @@ -591,12 +604,12 @@ void __init s3c24xx_init_irq(void) | |||
| 591 | 604 | ||
| 592 | last = 0; | 605 | last = 0; |
| 593 | for (i = 0; i < 4; i++) { | 606 | for (i = 0; i < 4; i++) { |
| 594 | pend = __raw_readl(S3C2410_EINTPEND); | 607 | pend = __raw_readl(S3C24XX_EINTPEND); |
| 595 | 608 | ||
| 596 | if (pend == 0 || pend == last) | 609 | if (pend == 0 || pend == last) |
| 597 | break; | 610 | break; |
| 598 | 611 | ||
| 599 | __raw_writel(pend, S3C2410_EINTPEND); | 612 | __raw_writel(pend, S3C24XX_EINTPEND); |
| 600 | printk("irq: clearing pending ext status %08x\n", (int)pend); | 613 | printk("irq: clearing pending ext status %08x\n", (int)pend); |
| 601 | last = pend; | 614 | last = pend; |
| 602 | } | 615 | } |
| @@ -630,12 +643,14 @@ void __init s3c24xx_init_irq(void) | |||
| 630 | 643 | ||
| 631 | irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n"); | 644 | irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n"); |
| 632 | 645 | ||
| 633 | for (irqno = IRQ_BATT_FLT; irqno <= IRQ_ADCPARENT; irqno++) { | 646 | for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) { |
| 634 | /* set all the s3c2410 internal irqs */ | 647 | /* set all the s3c2410 internal irqs */ |
| 635 | 648 | ||
| 636 | switch (irqno) { | 649 | switch (irqno) { |
| 637 | /* deal with the special IRQs (cascaded) */ | 650 | /* deal with the special IRQs (cascaded) */ |
| 638 | 651 | ||
| 652 | case IRQ_EINT4t7: | ||
| 653 | case IRQ_EINT8t23: | ||
| 639 | case IRQ_UART0: | 654 | case IRQ_UART0: |
| 640 | case IRQ_UART1: | 655 | case IRQ_UART1: |
| 641 | case IRQ_UART2: | 656 | case IRQ_UART2: |
| @@ -659,12 +674,14 @@ void __init s3c24xx_init_irq(void) | |||
| 659 | 674 | ||
| 660 | /* setup the cascade irq handlers */ | 675 | /* setup the cascade irq handlers */ |
| 661 | 676 | ||
| 677 | set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint); | ||
| 678 | set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint); | ||
| 679 | |||
| 662 | set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); | 680 | set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); |
| 663 | set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); | 681 | set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); |
| 664 | set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2); | 682 | set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2); |
| 665 | set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc); | 683 | set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc); |
| 666 | 684 | ||
| 667 | |||
| 668 | /* external interrupts */ | 685 | /* external interrupts */ |
| 669 | 686 | ||
| 670 | for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { | 687 | for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { |
diff --git a/include/asm-arm/arch-s3c2410/entry-macro.S b/include/asm-arm/arch-s3c2410/entry-macro.S index 894c35cf3b1e..e09a6b8ec153 100644 --- a/include/asm-arm/arch-s3c2410/entry-macro.S +++ b/include/asm-arm/arch-s3c2410/entry-macro.S | |||
| @@ -18,8 +18,6 @@ | |||
| 18 | 18 | ||
| 19 | #define INTPND (0x10) | 19 | #define INTPND (0x10) |
| 20 | #define INTOFFSET (0x14) | 20 | #define INTOFFSET (0x14) |
| 21 | #define EXTINTPEND (0xa8) | ||
| 22 | #define EXTINTMASK (0xa4) | ||
| 23 | 21 | ||
| 24 | #include <asm/hardware.h> | 22 | #include <asm/hardware.h> |
| 25 | #include <asm/arch/irqs.h> | 23 | #include <asm/arch/irqs.h> |
| @@ -28,37 +26,23 @@ | |||
| 28 | 26 | ||
| 29 | mov \base, #S3C24XX_VA_IRQ | 27 | mov \base, #S3C24XX_VA_IRQ |
| 30 | 28 | ||
| 31 | ldr \irqstat, [ \base, #INTPND] | ||
| 32 | bics \irqnr, \irqstat, #3<<4 @@ only an GPIO IRQ | ||
| 33 | beq 2000f | ||
| 34 | |||
| 35 | @@ try the interrupt offset register, since it is there | 29 | @@ try the interrupt offset register, since it is there |
| 36 | 30 | ||
| 31 | ldr \irqstat, [ \base, #INTPND ] | ||
| 32 | teq \irqstat, #0 | ||
| 33 | beq 1002f | ||
| 37 | ldr \irqnr, [ \base, #INTOFFSET ] | 34 | ldr \irqnr, [ \base, #INTOFFSET ] |
| 38 | mov \tmp, #1 | 35 | mov \tmp, #1 |
| 39 | tst \irqstat, \tmp, lsl \irqnr | 36 | tst \irqstat, \tmp, lsl \irqnr |
| 40 | addne \irqnr, \irqnr, #IRQ_EINT0 | ||
| 41 | bne 1001f | 37 | bne 1001f |
| 42 | 38 | ||
| 43 | @@ the number specified is not a valid irq, so try | 39 | @@ the number specified is not a valid irq, so try |
| 44 | @@ and work it out for ourselves | 40 | @@ and work it out for ourselves |
| 45 | 41 | ||
| 46 | mov \irqnr, #IRQ_EINT0 @@ start here | 42 | mov \irqnr, #0 @@ start here |
| 47 | b 3000f | ||
| 48 | |||
| 49 | 2000: | ||
| 50 | @@ load the GPIO interrupt register, and check it | ||
| 51 | |||
| 52 | add \tmp, \base, #S3C24XX_VA_GPIO - S3C24XX_VA_IRQ | ||
| 53 | ldr \irqstat, [ \tmp, # EXTINTPEND ] | ||
| 54 | ldr \irqnr, [ \tmp, # EXTINTMASK ] | ||
| 55 | bics \irqstat, \irqstat, \irqnr | ||
| 56 | beq 1001f | ||
| 57 | |||
| 58 | mov \irqnr, #(IRQ_EINT4 - 4) | ||
| 59 | 43 | ||
| 60 | @@ work out which irq (if any) we got | 44 | @@ work out which irq (if any) we got |
| 61 | 3000: | 45 | |
| 62 | movs \tmp, \irqstat, lsl#16 | 46 | movs \tmp, \irqstat, lsl#16 |
| 63 | addeq \irqnr, \irqnr, #16 | 47 | addeq \irqnr, \irqnr, #16 |
| 64 | moveq \irqstat, \irqstat, lsr#16 | 48 | moveq \irqstat, \irqstat, lsr#16 |
| @@ -75,9 +59,9 @@ | |||
| 75 | addeq \irqnr, \irqnr, #1 | 59 | addeq \irqnr, \irqnr, #1 |
| 76 | 60 | ||
| 77 | @@ we have the value | 61 | @@ we have the value |
| 78 | movs \irqnr, \irqnr | ||
| 79 | |||
| 80 | 1001: | 62 | 1001: |
| 63 | adds \irqnr, \irqnr, #IRQ_EINT0 | ||
| 64 | 1002: | ||
| 81 | @@ exit here, Z flag unset if IRQ | 65 | @@ exit here, Z flag unset if IRQ |
| 82 | 66 | ||
| 83 | .endm | 67 | .endm |
diff --git a/include/asm-arm/arch-s3c2410/regs-irq.h b/include/asm-arm/arch-s3c2410/regs-irq.h index 24b7292df79e..572fca5d9acf 100644 --- a/include/asm-arm/arch-s3c2410/regs-irq.h +++ b/include/asm-arm/arch-s3c2410/regs-irq.h | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | #define S3C2410_IRQREG(x) ((x) + S3C24XX_VA_IRQ) | 24 | #define S3C2410_IRQREG(x) ((x) + S3C24XX_VA_IRQ) |
| 25 | #define S3C2410_EINTREG(x) ((x) + S3C24XX_VA_GPIO) | 25 | #define S3C2410_EINTREG(x) ((x) + S3C24XX_VA_GPIO) |
| 26 | #define S3C24XX_EINTREG(x) ((x) + S3C24XX_VA_GPIO2) | ||
| 26 | 27 | ||
| 27 | #define S3C2410_SRCPND S3C2410_IRQREG(0x000) | 28 | #define S3C2410_SRCPND S3C2410_IRQREG(0x000) |
| 28 | #define S3C2410_INTMOD S3C2410_IRQREG(0x004) | 29 | #define S3C2410_INTMOD S3C2410_IRQREG(0x004) |
| @@ -40,5 +41,10 @@ | |||
| 40 | 41 | ||
| 41 | #define S3C2410_EINTMASK S3C2410_EINTREG(0x0A4) | 42 | #define S3C2410_EINTMASK S3C2410_EINTREG(0x0A4) |
| 42 | #define S3C2410_EINTPEND S3C2410_EINTREG(0X0A8) | 43 | #define S3C2410_EINTPEND S3C2410_EINTREG(0X0A8) |
| 44 | #define S3C2412_EINTMASK S3C2410_EINTREG(0x0B4) | ||
| 45 | #define S3C2412_EINTPEND S3C2410_EINTREG(0X0B8) | ||
| 46 | |||
| 47 | #define S3C24XX_EINTMASK S3C24XX_EINTREG(0x0A4) | ||
| 48 | #define S3C24XX_EINTPEND S3C24XX_EINTREG(0X0A8) | ||
| 43 | 49 | ||
| 44 | #endif /* ___ASM_ARCH_REGS_IRQ_H */ | 50 | #endif /* ___ASM_ARCH_REGS_IRQ_H */ |
