[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 cc10a093a5455fa9f1b156b502c5346e64a985b6..d645897652c2d50a073bc529533127beff369c8d 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 6f5e7c50d42ff2d78bd9b29d050f9902904f1af7..c589dc3ecd1ac0fb48cc619496fd3456649cb0a6 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 1eb3503bd16e1a78303a610eb4723422cde8988a..83fdf68f6b7c9c216a1d6bbfe6152089fa414785 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 57248a796472215ba376cdf59763c19b92ec0fd8..0e0aadf2a175b28be92f8a789a9943985122f3e1 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 c9e5395e510614a50259c4cd5719d724f4320ad9..0cfb89b229d18da94b1595aa4d429b1d24a5f7ab 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 de4481dd8ba0ebe6fbc21dc11f9c9bcf9e55ee52..cd8c5a0bc7bce6dfae9b8060b4347840a4b539d6 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 b12ca04f998c657feaacb1cc5e0a680d16ed0e6f..aa23c5d6c69e4b4b31daf9ca1726f53daf10dcc6 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 ce812d4f4a33687cdbd2deeadfec5508331619fc..4203dbf106624d95a8955f953e968822579af99b 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 84140a28dfcf8bec343ef7a3341ac1671b9a8341..241ec221a0471e4bef8f71a253e5db061ce394d1 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 8f165648e2af0718a5d21e9fbc40ceea6987be00..38dd63ae104ea4c3c78f3f60fb645b477fb38cda 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 3b9ef69146275a68929602e67f773b238f676348..d8cbafa6cc49d25514df36f6d4c7de1486ec8336 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 69838d04f90bc9882c36c06ffa65a3b513737021..491af1a23de55ca28cf35703009ce72e30142d68 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 94c50283dc56388f5cce96ba78ea0536d71f03f3..a624a7870c64b36deb67a91598af6e765fbbeba6 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 1500cbbd2295802644dbea87c3575e8477f5e98d..207db99dfbd2130f655235cc86d447817dd2216a 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 92b791702e3418fbf85fc80d52212f4d54b46457..b8e3d449e88276fb271430cd7315b8848417e2be 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 16e1e6124b319bec4e7b043abb3e13c9d126229d..11d512ad594586274e147cf64d8402ed65336deb 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 867761677b572d6c17816284a6d42bd88d2fcd14..ec9dd6fc2d0f6592d44dcd2f0d96023d2cb7ea2c 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 27e124132e4cde02926eae5b52aeb26cdefbd896..dadb568b7ef0f07a00c747e61b3f57836bbe7ead 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 8b6342dc4be2aaee619483e76e0bbcbfc62cd641..63411d3e9df49e87108215364d29a55bb8b4f53f 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 9fc7f4988124af1b81247778df5890095e6acd6f..502700604e0000752716988e64f1a13bde66e56a 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 658df4d60ff36f13836a34b14fc0d4d39cbe5651..83ad188a08474c4239224526282ef6d6f22deb04 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 0ffb1185f1ac90b930fd486e6fe57c85bf0a0bcd..c90dff4828f730f9bc8d8b2a1760e716f46ea75c 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 c1c198e3680bde3bf442be47b3ab469bc2c573dc..f11731974e5d5a2b2b3123783b16cb8b7bc19375 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 4985e33afc12de2cc389dad3e76dc60182345d57..1d5fbb9b379a03652b3c8347ef1adaed15bce146 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 1a6eec86bd476581b0e29f5ae566d9a49c61d27b..138838d4ad7575460b0995cb2b9cf3d90c0aa39a 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 c9e5395e510614a50259c4cd5719d724f4320ad9..0cfb89b229d18da94b1595aa4d429b1d24a5f7ab 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 1eb4e6b8d249c70ed2a53be4c7252aed5dbaf23c..bbec0a8ff158649b8d828f3aa97e44ee811bcb88 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 51fb50ce11690eb4dc48fad0108deb53e234af82..028967629340b60164cc98061b78443703a7e50c 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 a924f27fb8d98c7161a26f90aae9f4dc0808c4b2..82463f30f3dfc7e02dcbbafd270e352aa1c1a048 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 feff771c0a0a950630cbef18d231da9c5d665d47..0fae002637a06c832db730c9796c229d4dfdee24 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