Commit 26f91fd5 authored by Ben Dooks's avatar Ben Dooks Committed by Russell King

[ARM] 3443/1: [S3C2410] Improve IRQ entry code

Patch from Ben Dooks

Remove the old debug from the IRQ entry code,
update the comments on the handling of the
IRQ registers.

The message "bad interrupt offset" is removed
as it is only helpful for debugging, and can
cause printk() flooding when under load.

Make the code to deal with GPIO interrupts
faster, and use the same path to deal with
unexplained results from the IRQ registers.
Signed-off-by: default avatarBen Dooks <ben-linux@fluff.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 23759dc6
...@@ -6,116 +6,83 @@ ...@@ -6,116 +6,83 @@
* This file is licensed under the terms of the GNU General Public * This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any * License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied. * warranty of any kind, whether express or implied.
*/
/* We have a problem that the INTOFFSET register does not always
* show one interrupt. Occasionally we get two interrupts through
* the prioritiser, and this causes the INTOFFSET register to show
* what looks like the logical-or of the two interrupt numbers.
*
* Thanks to Klaus, Shannon, et al for helping to debug this problem
*/
#define INTPND (0x10)
#define INTOFFSET (0x14)
#define EXTINTPEND (0xa8)
#define EXTINTMASK (0xa4)
* Modifications:
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/arch/irqs.h> #include <asm/arch/irqs.h>
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov \tmp, #S3C24XX_VA_IRQ mov \base, #S3C24XX_VA_IRQ
ldr \irqnr, [ \tmp, #0x14 ] @ get irq no
30000: ldr \irqstat, [ \base, #INTPND]
teq \irqnr, #4 bics \irqnr, \irqstat, #3<<4 @@ only an GPIO IRQ
teqne \irqnr, #5 beq 2000f
beq 1002f @ external irq reg
@@ try the interrupt offset register, since it is there
@ debug check to see if interrupt reported is the same
@ as the offset.... ldr \irqnr, [ \base, #INTOFFSET ]
mov \tmp, #1
teq \irqnr, #0 tst \irqstat, \tmp, lsl \irqnr
beq 20002f addne \irqnr, \irqnr, #IRQ_EINT0
ldr \irqstat, [ \tmp, #0x10 ] @ INTPND bne 1001f
mov \irqstat, \irqstat, lsr \irqnr
tst \irqstat, #1 @@ the number specified is not a valid irq, so try
bne 20002f @@ and work it out for ourselves
/* debug/warning if we get an invalud response from the mov \irqnr, #IRQ_EINT0 @@ start here
* INTOFFSET register */ b 3000f
#if 1
stmfd r13!, { r0 - r4 , r8-r12, r14 } 2000:
ldr r1, [ \tmp, #0x14 ] @ INTOFFSET @@ load the GPIO interrupt register, and check it
ldr r2, [ \tmp, #0x10 ] @ INTPND
ldr r3, [ \tmp, #0x00 ] @ SRCPND add \tmp, \base, #S3C24XX_VA_GPIO - S3C24XX_VA_IRQ
adr r0, 20003f ldr \irqstat, [ \tmp, # EXTINTPEND ]
bl printk ldr \irqnr, [ \tmp, # EXTINTMASK ]
b 20004f bics \irqstat, \irqstat, \irqnr
beq 1001f
20003:
.ascii "<7>irq: err - bad offset %d, intpnd=%08x, srcpnd=%08x\n" mov \irqnr, #(IRQ_EINT4 - 4)
.byte 0
.align 4 @@ work out which irq (if any) we got
20004: 3000:
mov r1, #1 movs \tmp, \irqstat, lsl#16
mov \tmp, #S3C24XX_VA_IRQ addeq \irqnr, \irqnr, #16
ldmfd r13!, { r0 - r4 , r8-r12, r14 } moveq \irqstat, \irqstat, lsr#16
#endif tst \irqstat, #0xff
addeq \irqnr, \irqnr, #8
@ try working out interrupt number for ourselves moveq \irqstat, \irqstat, lsr#8
mov \irqnr, #0 tst \irqstat, #0xf
ldr \irqstat, [ \tmp, #0x10 ] @ INTPND addeq \irqnr, \irqnr, #4
10021: moveq \irqstat, \irqstat, lsr#4
movs \irqstat, \irqstat, lsr#1 tst \irqstat, #0x3
bcs 30000b @ try and re-start the proccess addeq \irqnr, \irqnr, #2
add \irqnr, \irqnr, #1 moveq \irqstat, \irqstat, lsr#2
cmp \irqnr, #32 tst \irqstat, #0x1
ble 10021b addeq \irqnr, \irqnr, #1
@ found no interrupt, set Z flag and leave @@ we have the value
movs \irqnr, #0 movs \irqnr, \irqnr
b 1001f
20005:
20002: @ exit
@ we base the s3c2410x interrupts at 16 and above to allow
@ isa peripherals to have their standard interrupts, also
@ ensure that Z flag is un-set on exit
@ note, we cannot be sure if we get IRQ_EINT0 (0) that
@ there is simply no interrupt pending, so in all other
@ cases we jump to say we have found something, otherwise
@ we check to see if the interrupt really is assrted
adds \irqnr, \irqnr, #IRQ_EINT0
teq \irqnr, #IRQ_EINT0
bne 1001f @ exit
ldr \irqstat, [ \tmp, #0x10 ] @ INTPND
teq \irqstat, #0
moveq \irqnr, #0
b 1001f
@ we get here from no main or external interrupts pending
1002:
add \tmp, \tmp, #S3C24XX_VA_GPIO - S3C24XX_VA_IRQ
ldr \irqstat, [ \tmp, # 0xa8 ] @ EXTINTPEND
ldr \irqnr, [ \tmp, # 0xa4 ] @ EXTINTMASK
bic \irqstat, \irqstat, \irqnr @ clear masked irqs
mov \irqnr, #IRQ_EINT4 @ start extint nos
mov \irqstat, \irqstat, lsr#4 @ ignore bottom 4 bits
10021:
movs \irqstat, \irqstat, lsr#1
bcs 1004f
add \irqnr, \irqnr, #1
cmp \irqnr, #IRQ_EINT23
ble 10021b
@ found no interrupt, set Z flag and leave
movs \irqnr, #0
1004: @ ensure Z flag clear in case our MOVS shifted out the last bit
teq \irqnr, #0
1001: 1001:
@ exit irq routine @@ exit here, Z flag unset if IRQ
.endm
.endm
/* currently don't need an disable_fiq macro */ /* currently don't need an disable_fiq macro */
.macro disable_fiq .macro disable_fiq
.endm .endm
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment