[ARM] 4185/2: entry: introduce get_irqnr_preamble and arch_ret_to_user
authorDan Williams <dan.j.williams@intel.com>
Fri, 16 Feb 2007 21:16:32 +0000 (22:16 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 17 Feb 2007 15:04:29 +0000 (15:04 +0000)
get_irqnr_preamble allows machines to take some action before entering the
get_irqnr_and_base loop.  On iop we enable cp6 access.

arch_ret_to_user is added to the userspace return path to allow individual
architectures to take actions, like disabling coprocessor access, before
the final return to userspace.

Per Nicolas Pitre's note, there is no need to cp_wait on the return to user
as the latency to return is sufficient.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
30 files changed:
arch/arm/kernel/entry-armv.S
arch/arm/kernel/entry-common.S
include/asm-arm/arch-aaec2000/entry-macro.S
include/asm-arm/arch-at91rm9200/entry-macro.S
include/asm-arm/arch-cl7500/entry-macro.S
include/asm-arm/arch-clps711x/entry-macro.S
include/asm-arm/arch-ebsa110/entry-macro.S
include/asm-arm/arch-ebsa285/entry-macro.S
include/asm-arm/arch-ep93xx/entry-macro.S
include/asm-arm/arch-h720x/entry-macro.S
include/asm-arm/arch-imx/entry-macro.S
include/asm-arm/arch-integrator/entry-macro.S
include/asm-arm/arch-iop13xx/entry-macro.S
include/asm-arm/arch-iop32x/entry-macro.S
include/asm-arm/arch-iop33x/entry-macro.S
include/asm-arm/arch-ixp2000/entry-macro.S
include/asm-arm/arch-ixp23xx/entry-macro.S
include/asm-arm/arch-ixp4xx/entry-macro.S
include/asm-arm/arch-l7200/entry-macro.S
include/asm-arm/arch-lh7a40x/entry-macro.S
include/asm-arm/arch-netx/entry-macro.S
include/asm-arm/arch-omap/entry-macro.S
include/asm-arm/arch-pnx4008/entry-macro.S
include/asm-arm/arch-pxa/entry-macro.S
include/asm-arm/arch-realview/entry-macro.S
include/asm-arm/arch-rpc/entry-macro.S
include/asm-arm/arch-s3c2410/entry-macro.S
include/asm-arm/arch-sa1100/entry-macro.S
include/asm-arm/arch-shark/entry-macro.S
include/asm-arm/arch-versatile/entry-macro.S

index cc10a09..d645897 100644 (file)
@@ -27,6 +27,7 @@
  * Interrupt handling.  Preserves r7, r8, r9
  */
        .macro  irq_handler
+       get_irqnr_preamble r5, lr
 1:     get_irqnr_and_base r0, r6, r5, lr
        movne   r1, sp
        @
index 6f5e7c5..c589dc3 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <asm/unistd.h>
+#include <asm/arch/entry-macro.S>
 
 #include "entry-header.S"
 
@@ -25,6 +26,9 @@ ret_fast_syscall:
        tst     r1, #_TIF_WORK_MASK
        bne     fast_work_pending
 
+       /* perform architecture specific actions before user return */
+       arch_ret_to_user r1, lr
+
        @ fast_restore_user_regs
        ldr     r1, [sp, #S_OFF + S_PSR]        @ get calling cpsr
        ldr     lr, [sp, #S_OFF + S_PC]!        @ get pc
@@ -61,6 +65,9 @@ ret_slow_syscall:
        tst     r1, #_TIF_WORK_MASK
        bne     work_pending
 no_work_pending:
+       /* perform architecture specific actions before user return */
+       arch_ret_to_user r1, lr
+
        @ slow_restore_user_regs
        ldr     r1, [sp, #S_PSR]                @ get calling cpsr
        ldr     lr, [sp, #S_PC]!                @ get pc
index 1eb3503..83fdf68 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                mov     r4, #0xf8000000
                add     r4, r4, #0x00000500
index 57248a7..0e0aadf 100644 (file)
        .macro  disable_fiq
        .endm
 
+       .macro  get_irqnr_preamble, base, tmp
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
+
        .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
        ldr     \base, =(AT91_VA_BASE_SYS)              @ base virtual address of SYS peripherals
        ldr     \irqnr, [\base, #AT91_AIC_IVR]          @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)
index c9e5395..0cfb89b 100644 (file)
@@ -1,3 +1,8 @@
 #include <asm/hardware.h>
 #include <asm/hardware/entry-macro-iomd.S>
+       .macro  get_irqnr_preamble, base, tmp
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
 
index de4481d..cd8c5a0 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
 #if (INTSR2 - INTSR1) != (INTMR2 - INTMR1)
 #error INTSR stride != INTMR stride
 #endif
index b12ca04..aa23c5d 100644 (file)
        .macro  disable_fiq
        .endm
 
+       .macro  get_irqnr_preamble, base, tmp
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
+
        .macro  get_irqnr_and_base, irqnr, stat, base, tmp
        mov     \base, #IRQ_STAT
        ldrb    \stat, [\base]                  @ get interrupts
index ce812d4..4203dbf 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .equ    dc21285_high, ARMCSR_BASE & 0xff000000
                .equ    dc21285_low, ARMCSR_BASE & 0x00ffffff
 
index 84140a2..241ec22 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                ldr     \base, =(EP93XX_AHB_VIRT_BASE)
                orr     \base, \base, #0x000b0000
index 8f16564..38dd63a 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
 #if defined (CONFIG_CPU_H7201) || defined (CONFIG_CPU_H7202)
                @ we could use the id register on H7202, but this is not
index 3b9ef69..d8cbafa 100644 (file)
 
                .macro  disable_fiq
                .endm
+
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
 #define AITC_NIVECSR   0x40
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                ldr     \irqstat, =IO_ADDRESS(IMX_AITC_BASE)
index 69838d0..491af1a 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
 /* FIXME: should not be using soo many LDRs here */
                ldr     \base, =IO_ADDRESS(INTEGRATOR_IC_BASE)
index 94c5028..a624a78 100644 (file)
        .macro  disable_fiq
        .endm
 
+       .macro get_irqnr_preamble, base, tmp
+       mrc     p15, 0, \tmp, c15, c1, 0
+       orr     \tmp, \tmp, #(1 << 6)
+       mcr     p15, 0, \tmp, c15, c1, 0        @ Enable cp6 access
+       .endm
+
        /*
         * Note: a 1-cycle window exists where iintvec will return the value
         * of iintbase, so we explicitly check for "bad zeros"
         */
        .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-       mrc     p15, 0, \tmp, c15, c1, 0
-       orr     \tmp, \tmp, #(1 << 6)
-       mcr     p15, 0, \tmp, c15, c1, 0        @ Enable cp6 access
-
        mrc     p6, 0, \irqnr, c3, c2, 0        @ Read IINTVEC
        cmp     \irqnr, #0
        mrceq   p6, 0, \irqnr, c3, c2, 0        @ Re-read on potentially bad zero
        adds    \irqstat, \irqnr, #1            @ Check for 0xffffffff
        movne   \irqnr, \irqnr, lsr #2          @ Convert to irqnr
+       .endm
 
-       biceq   \tmp, \tmp, #(1 << 6)
-       mcreq   p15, 0, \tmp, c15, c1, 0        @ Disable cp6 access if no more interrupts
+       .macro arch_ret_to_user, tmp1, tmp2
+       mrc     p15, 0, \tmp1, c15, c1, 0
+       ands    \tmp2, \tmp1, #(1 << 6)
+       bicne   \tmp1, \tmp1, #(1 << 6)
+       mcrne   p15, 0, \tmp1, c15, c1, 0       @ Disable cp6 access
        .endm
index 1500cbb..207db99 100644 (file)
@@ -9,13 +9,28 @@
  */
 #include <asm/arch/iop32x.h>
 
-               .macro  disable_fiq
-               .endm
+       .macro  disable_fiq
+       .endm
 
-               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-               ldr     \base, =IOP3XX_REG_ADDR(0x07D8)
-               ldr     \irqstat, [\base]               @ Read IINTSRC
-               cmp     \irqstat, #0
-               clzne   \irqnr, \irqstat
-               rsbne   \irqnr, \irqnr, #31
-               .endm
+       .macro get_irqnr_preamble, base, tmp
+       mrc     p15, 0, \tmp, c15, c1, 0
+       orr     \tmp, \tmp, #(1 << 6)
+       mcr     p15, 0, \tmp, c15, c1, 0        @ Enable cp6 access
+       mrc     p15, 0, \tmp, c15, c1, 0
+       mov     \tmp, \tmp
+       sub     pc, pc, #4                      @ cp_wait
+       .endm
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+       mrc     p6, 0, \irqstat, c8, c0, 0      @ Read IINTSRC
+       cmp     \irqstat, #0
+       clzne   \irqnr, \irqstat
+       rsbne   \irqnr, \irqnr, #31
+       .endm
+
+       .macro arch_ret_to_user, tmp1, tmp2
+       mrc     p15, 0, \tmp1, c15, c1, 0
+       ands    \tmp2, \tmp1, #(1 << 6)
+       bicne   \tmp1, \tmp1, #(1 << 6)
+       mcrne   p15, 0, \tmp1, c15, c1, 0       @ Disable cp6 access
+       .endm
index 92b7917..b8e3d44 100644 (file)
@@ -9,14 +9,29 @@
  */
 #include <asm/arch/iop33x.h>
 
-               .macro  disable_fiq
-               .endm
+       .macro  disable_fiq
+       .endm
 
-               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-               ldr     \base, =IOP3XX_REG_ADDR(0x07C8)
-               ldr     \irqstat, [\base]               @ Read IINTVEC
-               cmp     \irqstat, #0
-               ldreq   \irqstat, [\base]               @ erratum 63 workaround
-               adds    \irqnr, \irqstat, #1
-               movne   \irqnr, \irqstat, lsr #2
-               .endm
+       .macro get_irqnr_preamble, base, tmp
+       mrc     p15, 0, \tmp, c15, c1, 0
+       orr     \tmp, \tmp, #(1 << 6)
+       mcr     p15, 0, \tmp, c15, c1, 0        @ Enable cp6 access
+       mrc     p15, 0, \tmp, c15, c1, 0
+       mov     \tmp, \tmp
+       sub     pc, pc, #4                      @ cp_wait
+       .endm
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+       mrc     p6, 0, \irqstat, c14, c0, 0     @ Read IINTVEC
+       cmp     \irqstat, #0
+       mrceq   p6, 0, \irqstat, c14, c0, 0     @ erratum 63 workaround
+       adds    \irqnr, \irqstat, #1
+       movne   \irqnr, \irqstat, lsr #2
+       .endm
+
+       .macro arch_ret_to_user, tmp1, tmp2
+       mrc     p15, 0, \tmp1, c15, c1, 0
+       ands    \tmp2, \tmp1, #(1 << 6)
+       bicne   \tmp1, \tmp1, #(1 << 6)
+       mcrne   p15, 0, \tmp1, c15, c1, 0       @ Disable cp6 access
+       .endm
index 16e1e61..11d512a 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
 
                mov     \irqnr, #0x0              @clear out irqnr as default
index 8677616..ec9dd6f 100644 (file)
@@ -5,6 +5,12 @@
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                ldr     \irqnr, =(IXP23XX_INTC_VIRT + IXP23XX_INTR_IRQ_ENC_ST_OFFSET)
                ldr     \irqnr, [\irqnr]        @ get interrupt number
index 27e1241..dadb568 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                ldr     \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET)
                ldr     \irqstat, [\irqstat]            @ get interrupts
index 8b6342d..63411d3 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                mov     \irqstat, #irq_base_addr                @ Virt addr IRQ regs
                add     \irqstat, \irqstat, #0x00001000         @ Status reg
index 9fc7f49..5027006 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
 
 branch_irq_lh7a400: b 1000f
index 658df4d..83ad188 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                mov     \base, #io_p2v(0x00100000)
                add     \base, \base, #0x000ff000
index 0ffb118..c90dff4 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                ldr     \base, =IO_ADDRESS(OMAP_IH1_BASE)
                ldr     \irqnr, [\base, #IRQ_ITR_REG_OFFSET]
index c1c198e..f117319 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
 /* decode the MIC interrupt numbers */
                ldr     \base, =IO_ADDRESS(PNX4008_INTCTRLMIC_BASE)
index 4985e33..1d5fbb9 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
 #ifdef CONFIG_PXA27x
                mrc     p6, 0, \irqstat, c0, c0, 0              @ ICIP
index 1a6eec8..138838d 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                /*
                 * The interrupt numbering scheme is defined in the
                 * interrupt controller spec.  To wit:
index c9e5395..0cfb89b 100644 (file)
@@ -1,3 +1,8 @@
 #include <asm/hardware.h>
 #include <asm/hardware/entry-macro-iomd.S>
+       .macro  get_irqnr_preamble, base, tmp
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
 
index 1eb4e6b..bbec0a8 100644 (file)
 #include <asm/hardware.h>
 #include <asm/irq.h>
 
+       .macro  get_irqnr_preamble, base, tmp
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
+
        .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
 
                mov     \base, #S3C24XX_VA_IRQ
index 51fb50c..0289676 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                mov     r4, #0xfa000000                 @ ICIP = 0xfa050000
                add     r4, r4, #0x00050000
index a924f27..82463f3 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                mov     r4, #0xe0000000
 
index feff771..0fae002 100644 (file)
                .macro  disable_fiq
                .endm
 
+               .macro  get_irqnr_preamble, base, tmp
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
                .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
                ldr     \base, =IO_ADDRESS(VERSATILE_VIC_BASE)
                ldr     \irqstat, [\base, #VIC_IRQ_STATUS]      @ get masked status