bcm2709: Simplify and strip down IRQ handler

This commit is contained in:
popcornmix
2014-06-20 17:19:27 +01:00
parent d50a101ba1
commit f8756b0e5c
2 changed files with 87 additions and 88 deletions

View File

@@ -1,5 +1,6 @@
#include <asm/assembler.h>
#ifndef CONFIG_ARCH_BCM2709
/*
* Interrupt handling. Preserves r7, r8, r9
*/
@@ -28,6 +29,7 @@
#endif
9997:
.endm
#endif
.macro arch_irq_handler, symbol_name
.align 5

View File

@@ -22,102 +22,99 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
.macro disable_fiq
.endm
.macro arch_ret_to_user, tmp1, tmp2
.endm
.macro get_irqnr_preamble, base, tmp
ldr \base, =IO_ADDRESS(ARMCTRL_IC_BASE)
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
.macro arch_ret_to_user, tmp1, tmp2
.endm
/* get core number */
mrc p15, 0, \base, c0, c0, 5
ubfx \base, \base, #0, #2
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
/* get core number */
mrc p15, 0, \tmp, c0, c0, 5
ubfx \tmp, \tmp, #0, #2
/* get core's local interrupt controller */
ldr \irqstat, = __io_address(ARM_LOCAL_IRQ_PENDING0) @ local interrupt source
add \irqstat, \irqstat, \base, lsl #2
ldr \tmp, [\irqstat]
#ifdef CONFIG_SMP
/* test for mailbox0 (IPI) interrupt */
tst \tmp, #0x10
beq 1030f
/* get core's local interrupt controller */
ldr \irqstat, = __io_address(ARM_LOCAL_IRQ_PENDING0) @ local interrupt source
add \irqstat, \irqstat, \tmp, lsl #2
ldr \tmp, [\irqstat]
/* ignore gpu interrupt */
bic \tmp, #0x100
/* ignore mailbox interrupts */
bics \tmp, #0xf0
beq 1005f
/* get core's mailbox interrupt control */
ldr \irqstat, = __io_address(ARM_LOCAL_MAILBOX0_CLR0) @ mbox_clr
add \irqstat, \irqstat, \base, lsl #4
ldr \tmp, [\irqstat]
clz \tmp, \tmp
rsb \irqnr, \tmp, #31
mov \tmp, #1
lsl \tmp, \irqnr
str \tmp, [\irqstat] @ clear interrupt source
dsb
mov r1, sp
adr lr, BSYM(1b)
b do_IPI
#endif
1030:
/* check gpu interrupt */
tst \tmp, #0x100
beq 1040f
@ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
@ N.B. CLZ is an ARM5 instruction.
mov \irqnr, #(ARM_IRQ_LOCAL_BASE + 31)
sub \irqstat, \tmp, #1
eor \irqstat, \irqstat, \tmp
clz \tmp, \irqstat
sub \irqnr, \tmp
b 1020f
1005:
/* get core number */
mrc p15, 0, \tmp, c0, c0, 5
ubfx \tmp, \tmp, #0, #2
ldr \base, =IO_ADDRESS(ARMCTRL_IC_BASE)
/* get masked status */
ldr \irqstat, [\base, #(ARM_IRQ_PEND0 - ARMCTRL_IC_BASE)]
mov \irqnr, #(ARM_IRQ0_BASE + 31)
and \tmp, \irqstat, #0x300 @ save bits 8 and 9
/* clear bits 8 and 9, and test */
bics \irqstat, \irqstat, #0x300
bne 1010f
cmp \tmp, #1
beq 1020f
cmp \tmp, #2
beq 1020f
cmp \tmp, #3
beq 1020f
/* get masked status */
ldr \irqstat, [\base, #(ARM_IRQ_PEND0 - ARMCTRL_IC_BASE)]
mov \irqnr, #(ARM_IRQ0_BASE + 31)
and \tmp, \irqstat, #0x300 @ save bits 8 and 9
/* clear bits 8 and 9, and test */
bics \irqstat, \irqstat, #0x300
bne 1010f
tst \tmp, #0x100
ldrne \irqstat, [\base, #(ARM_IRQ_PEND1 - ARMCTRL_IC_BASE)]
movne \irqnr, #(ARM_IRQ1_BASE + 31)
@ Mask out the interrupts also present in PEND0 - see SW-5809
bicne \irqstat, #((1<<7) | (1<<9) | (1<<10))
bicne \irqstat, #((1<<18) | (1<<19))
bne 1010f
tst \tmp, #0x200
ldrne \irqstat, [\base, #(ARM_IRQ_PEND2 - ARMCTRL_IC_BASE)]
movne \irqnr, #(ARM_IRQ2_BASE + 31)
@ Mask out the interrupts also present in PEND0 - see SW-5809
bicne \irqstat, #((1<<21) | (1<<22) | (1<<23) | (1<<24) | (1<<25))
bicne \irqstat, #((1<<30))
beq 1020f
tst \tmp, #0x100
ldrne \irqstat, [\base, #(ARM_IRQ_PEND1 - ARMCTRL_IC_BASE)]
movne \irqnr, #(ARM_IRQ1_BASE + 31)
@ Mask out the interrupts also present in PEND0 - see SW-5809
bicne \irqstat, #((1<<7) | (1<<9) | (1<<10))
bicne \irqstat, #((1<<18) | (1<<19))
bne 1010f
tst \tmp, #0x200
ldrne \irqstat, [\base, #(ARM_IRQ_PEND2 - ARMCTRL_IC_BASE)]
movne \irqnr, #(ARM_IRQ2_BASE + 31)
@ Mask out the interrupts also present in PEND0 - see SW-5809
bicne \irqstat, #((1<<21) | (1<<22) | (1<<23) | (1<<24) | (1<<25))
bicne \irqstat, #((1<<30))
beq 1020f
1010:
@ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
@ N.B. CLZ is an ARM5 instruction.
sub \tmp, \irqstat, #1
eor \irqstat, \irqstat, \tmp
clz \tmp, \irqstat
sub \irqnr, \tmp
@ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
sub \tmp, \irqstat, #1
eor \irqstat, \irqstat, \tmp
clz \tmp, \irqstat
sub \irqnr, \tmp
b 1050f
1040:
cmp \tmp, #0
beq 1020f
/* handle local (e.g. timer) interrupts */
@ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
mov \irqnr, #(ARM_IRQ_LOCAL_BASE + 31)
sub \irqstat, \tmp, #1
eor \irqstat, \irqstat, \tmp
clz \tmp, \irqstat
sub \irqnr, \tmp
1050:
mov r1, sp
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
adr lr, BSYM(1b)
b asm_do_IRQ
1020: @ EQ will be set if no irqs pending
.endm
.endm
.macro test_for_ipi, irqnr, irqstat, base, tmp
/* get core number */
mrc p15, 0, \tmp, c0, c0, 5
ubfx \tmp, \tmp, #0, #2
/* get core's mailbox interrupt control */
ldr \irqstat, = __io_address(ARM_LOCAL_MAILBOX0_CLR0) @ mbox_clr
add \irqstat, \irqstat, \tmp, lsl #4
ldr \tmp, [\irqstat]
cmp \tmp, #0
beq 1030f
clz \tmp, \tmp
rsb \irqnr, \tmp, #31
mov \tmp, #1
lsl \tmp, \irqnr
str \tmp, [\irqstat] @ clear interrupt source
dsb
1030: @ EQ will be set if no irqs pending
.endm
/*
* Interrupt handling. Preserves r7, r8, r9
*/
.macro arch_irq_handler_default
1: get_irqnr_and_base r0, r2, r6, lr
.endm