[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: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
23759dc643
commit
26f91fd54d
1 changed files with 56 additions and 89 deletions
|
@ -6,116 +6,83 @@
|
|||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
|
||||
* Modifications:
|
||||
* 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
|
||||
*/
|
||||
|
||||
/* 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)
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/arch/irqs.h>
|
||||
|
||||
|
||||
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
|
||||
|
||||
mov \tmp, #S3C24XX_VA_IRQ
|
||||
ldr \irqnr, [ \tmp, #0x14 ] @ get irq no
|
||||
30000:
|
||||
teq \irqnr, #4
|
||||
teqne \irqnr, #5
|
||||
beq 1002f @ external irq reg
|
||||
mov \base, #S3C24XX_VA_IRQ
|
||||
|
||||
@ debug check to see if interrupt reported is the same
|
||||
@ as the offset....
|
||||
ldr \irqstat, [ \base, #INTPND]
|
||||
bics \irqnr, \irqstat, #3<<4 @@ only an GPIO IRQ
|
||||
beq 2000f
|
||||
|
||||
teq \irqnr, #0
|
||||
beq 20002f
|
||||
ldr \irqstat, [ \tmp, #0x10 ] @ INTPND
|
||||
mov \irqstat, \irqstat, lsr \irqnr
|
||||
tst \irqstat, #1
|
||||
bne 20002f
|
||||
@@ try the interrupt offset register, since it is there
|
||||
|
||||
/* debug/warning if we get an invalud response from the
|
||||
* INTOFFSET register */
|
||||
#if 1
|
||||
stmfd r13!, { r0 - r4 , r8-r12, r14 }
|
||||
ldr r1, [ \tmp, #0x14 ] @ INTOFFSET
|
||||
ldr r2, [ \tmp, #0x10 ] @ INTPND
|
||||
ldr r3, [ \tmp, #0x00 ] @ SRCPND
|
||||
adr r0, 20003f
|
||||
bl printk
|
||||
b 20004f
|
||||
ldr \irqnr, [ \base, #INTOFFSET ]
|
||||
mov \tmp, #1
|
||||
tst \irqstat, \tmp, lsl \irqnr
|
||||
addne \irqnr, \irqnr, #IRQ_EINT0
|
||||
bne 1001f
|
||||
|
||||
20003:
|
||||
.ascii "<7>irq: err - bad offset %d, intpnd=%08x, srcpnd=%08x\n"
|
||||
.byte 0
|
||||
.align 4
|
||||
20004:
|
||||
mov r1, #1
|
||||
mov \tmp, #S3C24XX_VA_IRQ
|
||||
ldmfd r13!, { r0 - r4 , r8-r12, r14 }
|
||||
#endif
|
||||
@@ the number specified is not a valid irq, so try
|
||||
@@ and work it out for ourselves
|
||||
|
||||
@ try working out interrupt number for ourselves
|
||||
mov \irqnr, #0
|
||||
ldr \irqstat, [ \tmp, #0x10 ] @ INTPND
|
||||
10021:
|
||||
movs \irqstat, \irqstat, lsr#1
|
||||
bcs 30000b @ try and re-start the proccess
|
||||
add \irqnr, \irqnr, #1
|
||||
cmp \irqnr, #32
|
||||
ble 10021b
|
||||
mov \irqnr, #IRQ_EINT0 @@ start here
|
||||
b 3000f
|
||||
|
||||
@ found no interrupt, set Z flag and leave
|
||||
movs \irqnr, #0
|
||||
b 1001f
|
||||
2000:
|
||||
@@ load the GPIO interrupt register, and check it
|
||||
|
||||
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
|
||||
add \tmp, \base, #S3C24XX_VA_GPIO - S3C24XX_VA_IRQ
|
||||
ldr \irqstat, [ \tmp, # EXTINTPEND ]
|
||||
ldr \irqnr, [ \tmp, # EXTINTMASK ]
|
||||
bics \irqstat, \irqstat, \irqnr
|
||||
beq 1001f
|
||||
|
||||
@ 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
|
||||
mov \irqnr, #(IRQ_EINT4 - 4)
|
||||
|
||||
@ 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
|
||||
@@ work out which irq (if any) we got
|
||||
3000:
|
||||
movs \tmp, \irqstat, lsl#16
|
||||
addeq \irqnr, \irqnr, #16
|
||||
moveq \irqstat, \irqstat, lsr#16
|
||||
tst \irqstat, #0xff
|
||||
addeq \irqnr, \irqnr, #8
|
||||
moveq \irqstat, \irqstat, lsr#8
|
||||
tst \irqstat, #0xf
|
||||
addeq \irqnr, \irqnr, #4
|
||||
moveq \irqstat, \irqstat, lsr#4
|
||||
tst \irqstat, #0x3
|
||||
addeq \irqnr, \irqnr, #2
|
||||
moveq \irqstat, \irqstat, lsr#2
|
||||
tst \irqstat, #0x1
|
||||
addeq \irqnr, \irqnr, #1
|
||||
|
||||
bic \irqstat, \irqstat, \irqnr @ clear masked irqs
|
||||
@@ we have the value
|
||||
movs \irqnr, \irqnr
|
||||
|
||||
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:
|
||||
@ exit irq routine
|
||||
.endm
|
||||
@@ exit here, Z flag unset if IRQ
|
||||
|
||||
.endm
|
||||
|
||||
/* currently don't need an disable_fiq macro */
|
||||
|
||||
.macro disable_fiq
|
||||
.endm
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue