From f80dff9da07d81da16e3b842118d47b9febf9c01 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 16 Feb 2007 22:16:32 +0100 Subject: [ARM] 4185/2: entry: introduce get_irqnr_preamble and arch_ret_to_user 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 Signed-off-by: Russell King --- arch/arm/kernel/entry-armv.S | 1 + arch/arm/kernel/entry-common.S | 7 ++++++ include/asm-arm/arch-aaec2000/entry-macro.S | 6 +++++ include/asm-arm/arch-at91rm9200/entry-macro.S | 6 +++++ include/asm-arm/arch-cl7500/entry-macro.S | 5 ++++ include/asm-arm/arch-clps711x/entry-macro.S | 6 +++++ include/asm-arm/arch-ebsa110/entry-macro.S | 6 +++++ include/asm-arm/arch-ebsa285/entry-macro.S | 6 +++++ include/asm-arm/arch-ep93xx/entry-macro.S | 6 +++++ include/asm-arm/arch-h720x/entry-macro.S | 6 +++++ include/asm-arm/arch-imx/entry-macro.S | 7 ++++++ include/asm-arm/arch-integrator/entry-macro.S | 6 +++++ include/asm-arm/arch-iop13xx/entry-macro.S | 18 +++++++++----- include/asm-arm/arch-iop32x/entry-macro.S | 33 ++++++++++++++++++------- include/asm-arm/arch-iop33x/entry-macro.S | 35 +++++++++++++++++++-------- include/asm-arm/arch-ixp2000/entry-macro.S | 6 +++++ include/asm-arm/arch-ixp23xx/entry-macro.S | 6 +++++ include/asm-arm/arch-ixp4xx/entry-macro.S | 6 +++++ include/asm-arm/arch-l7200/entry-macro.S | 6 +++++ include/asm-arm/arch-lh7a40x/entry-macro.S | 6 +++++ include/asm-arm/arch-netx/entry-macro.S | 6 +++++ include/asm-arm/arch-omap/entry-macro.S | 6 +++++ include/asm-arm/arch-pnx4008/entry-macro.S | 6 +++++ include/asm-arm/arch-pxa/entry-macro.S | 6 +++++ include/asm-arm/arch-realview/entry-macro.S | 6 +++++ include/asm-arm/arch-rpc/entry-macro.S | 5 ++++ include/asm-arm/arch-s3c2410/entry-macro.S | 6 +++++ include/asm-arm/arch-sa1100/entry-macro.S | 6 +++++ include/asm-arm/arch-shark/entry-macro.S | 6 +++++ include/asm-arm/arch-versatile/entry-macro.S | 6 +++++ 30 files changed, 218 insertions(+), 25 deletions(-) diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index cc10a093a545..d645897652c2 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -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 @ diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 6f5e7c50d42f..c589dc3ecd1a 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -9,6 +9,7 @@ */ #include +#include #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 diff --git a/include/asm-arm/arch-aaec2000/entry-macro.S b/include/asm-arm/arch-aaec2000/entry-macro.S index 1eb3503bd16e..83fdf68f6b7c 100644 --- a/include/asm-arm/arch-aaec2000/entry-macro.S +++ b/include/asm-arm/arch-aaec2000/entry-macro.S @@ -15,6 +15,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 mov r4, #0xf8000000 add r4, r4, #0x00000500 diff --git a/include/asm-arm/arch-at91rm9200/entry-macro.S b/include/asm-arm/arch-at91rm9200/entry-macro.S index 57248a796472..0e0aadf2a175 100644 --- a/include/asm-arm/arch-at91rm9200/entry-macro.S +++ b/include/asm-arm/arch-at91rm9200/entry-macro.S @@ -16,6 +16,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 \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) diff --git a/include/asm-arm/arch-cl7500/entry-macro.S b/include/asm-arm/arch-cl7500/entry-macro.S index c9e5395e5106..0cfb89b229d1 100644 --- a/include/asm-arm/arch-cl7500/entry-macro.S +++ b/include/asm-arm/arch-cl7500/entry-macro.S @@ -1,3 +1,8 @@ #include #include + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm diff --git a/include/asm-arm/arch-clps711x/entry-macro.S b/include/asm-arm/arch-clps711x/entry-macro.S index de4481dd8ba0..cd8c5a0bc7bc 100644 --- a/include/asm-arm/arch-clps711x/entry-macro.S +++ b/include/asm-arm/arch-clps711x/entry-macro.S @@ -13,6 +13,12 @@ .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 diff --git a/include/asm-arm/arch-ebsa110/entry-macro.S b/include/asm-arm/arch-ebsa110/entry-macro.S index b12ca04f998c..aa23c5d6c69e 100644 --- a/include/asm-arm/arch-ebsa110/entry-macro.S +++ b/include/asm-arm/arch-ebsa110/entry-macro.S @@ -15,6 +15,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, stat, base, tmp mov \base, #IRQ_STAT ldrb \stat, [\base] @ get interrupts diff --git a/include/asm-arm/arch-ebsa285/entry-macro.S b/include/asm-arm/arch-ebsa285/entry-macro.S index ce812d4f4a33..4203dbf10662 100644 --- a/include/asm-arm/arch-ebsa285/entry-macro.S +++ b/include/asm-arm/arch-ebsa285/entry-macro.S @@ -14,6 +14,12 @@ .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 diff --git a/include/asm-arm/arch-ep93xx/entry-macro.S b/include/asm-arm/arch-ep93xx/entry-macro.S index 84140a28dfcf..241ec221a047 100644 --- a/include/asm-arm/arch-ep93xx/entry-macro.S +++ b/include/asm-arm/arch-ep93xx/entry-macro.S @@ -14,6 +14,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 \base, =(EP93XX_AHB_VIRT_BASE) orr \base, \base, #0x000b0000 diff --git a/include/asm-arm/arch-h720x/entry-macro.S b/include/asm-arm/arch-h720x/entry-macro.S index 8f165648e2af..38dd63ae104e 100644 --- a/include/asm-arm/arch-h720x/entry-macro.S +++ b/include/asm-arm/arch-h720x/entry-macro.S @@ -11,6 +11,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 #if defined (CONFIG_CPU_H7201) || defined (CONFIG_CPU_H7202) @ we could use the id register on H7202, but this is not diff --git a/include/asm-arm/arch-imx/entry-macro.S b/include/asm-arm/arch-imx/entry-macro.S index 3b9ef6914627..d8cbafa6cc49 100644 --- a/include/asm-arm/arch-imx/entry-macro.S +++ b/include/asm-arm/arch-imx/entry-macro.S @@ -11,6 +11,13 @@ .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) diff --git a/include/asm-arm/arch-integrator/entry-macro.S b/include/asm-arm/arch-integrator/entry-macro.S index 69838d04f90b..491af1a23de5 100644 --- a/include/asm-arm/arch-integrator/entry-macro.S +++ b/include/asm-arm/arch-integrator/entry-macro.S @@ -13,6 +13,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 /* FIXME: should not be using soo many LDRs here */ ldr \base, =IO_ADDRESS(INTEGRATOR_IC_BASE) diff --git a/include/asm-arm/arch-iop13xx/entry-macro.S b/include/asm-arm/arch-iop13xx/entry-macro.S index 94c50283dc56..a624a7870c64 100644 --- a/include/asm-arm/arch-iop13xx/entry-macro.S +++ b/include/asm-arm/arch-iop13xx/entry-macro.S @@ -19,21 +19,27 @@ .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 diff --git a/include/asm-arm/arch-iop32x/entry-macro.S b/include/asm-arm/arch-iop32x/entry-macro.S index 1500cbbd2295..207db99dfbd2 100644 --- a/include/asm-arm/arch-iop32x/entry-macro.S +++ b/include/asm-arm/arch-iop32x/entry-macro.S @@ -9,13 +9,28 @@ */ #include - .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 diff --git a/include/asm-arm/arch-iop33x/entry-macro.S b/include/asm-arm/arch-iop33x/entry-macro.S index 92b791702e34..b8e3d449e882 100644 --- a/include/asm-arm/arch-iop33x/entry-macro.S +++ b/include/asm-arm/arch-iop33x/entry-macro.S @@ -9,14 +9,29 @@ */ #include - .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 diff --git a/include/asm-arm/arch-ixp2000/entry-macro.S b/include/asm-arm/arch-ixp2000/entry-macro.S index 16e1e6124b31..11d512ad5945 100644 --- a/include/asm-arm/arch-ixp2000/entry-macro.S +++ b/include/asm-arm/arch-ixp2000/entry-macro.S @@ -12,6 +12,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 mov \irqnr, #0x0 @clear out irqnr as default diff --git a/include/asm-arm/arch-ixp23xx/entry-macro.S b/include/asm-arm/arch-ixp23xx/entry-macro.S index 867761677b57..ec9dd6fc2d0f 100644 --- a/include/asm-arm/arch-ixp23xx/entry-macro.S +++ b/include/asm-arm/arch-ixp23xx/entry-macro.S @@ -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 diff --git a/include/asm-arm/arch-ixp4xx/entry-macro.S b/include/asm-arm/arch-ixp4xx/entry-macro.S index 27e124132e4c..dadb568b7ef0 100644 --- a/include/asm-arm/arch-ixp4xx/entry-macro.S +++ b/include/asm-arm/arch-ixp4xx/entry-macro.S @@ -12,6 +12,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 \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET) ldr \irqstat, [\irqstat] @ get interrupts diff --git a/include/asm-arm/arch-l7200/entry-macro.S b/include/asm-arm/arch-l7200/entry-macro.S index 8b6342dc4be2..63411d3e9df4 100644 --- a/include/asm-arm/arch-l7200/entry-macro.S +++ b/include/asm-arm/arch-l7200/entry-macro.S @@ -14,6 +14,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 mov \irqstat, #irq_base_addr @ Virt addr IRQ regs add \irqstat, \irqstat, #0x00001000 @ Status reg diff --git a/include/asm-arm/arch-lh7a40x/entry-macro.S b/include/asm-arm/arch-lh7a40x/entry-macro.S index 9fc7f4988124..502700604e00 100644 --- a/include/asm-arm/arch-lh7a40x/entry-macro.S +++ b/include/asm-arm/arch-lh7a40x/entry-macro.S @@ -26,6 +26,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 branch_irq_lh7a400: b 1000f diff --git a/include/asm-arm/arch-netx/entry-macro.S b/include/asm-arm/arch-netx/entry-macro.S index 658df4d60ff3..83ad188a0847 100644 --- a/include/asm-arm/arch-netx/entry-macro.S +++ b/include/asm-arm/arch-netx/entry-macro.S @@ -23,6 +23,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 mov \base, #io_p2v(0x00100000) add \base, \base, #0x000ff000 diff --git a/include/asm-arm/arch-omap/entry-macro.S b/include/asm-arm/arch-omap/entry-macro.S index 0ffb1185f1ac..c90dff4828f7 100644 --- a/include/asm-arm/arch-omap/entry-macro.S +++ b/include/asm-arm/arch-omap/entry-macro.S @@ -29,6 +29,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 \base, =IO_ADDRESS(OMAP_IH1_BASE) ldr \irqnr, [\base, #IRQ_ITR_REG_OFFSET] diff --git a/include/asm-arm/arch-pnx4008/entry-macro.S b/include/asm-arm/arch-pnx4008/entry-macro.S index c1c198e3680b..f11731974e5d 100644 --- a/include/asm-arm/arch-pnx4008/entry-macro.S +++ b/include/asm-arm/arch-pnx4008/entry-macro.S @@ -28,6 +28,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 /* decode the MIC interrupt numbers */ ldr \base, =IO_ADDRESS(PNX4008_INTCTRLMIC_BASE) diff --git a/include/asm-arm/arch-pxa/entry-macro.S b/include/asm-arm/arch-pxa/entry-macro.S index 4985e33afc12..1d5fbb9b379a 100644 --- a/include/asm-arm/arch-pxa/entry-macro.S +++ b/include/asm-arm/arch-pxa/entry-macro.S @@ -13,6 +13,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 #ifdef CONFIG_PXA27x mrc p6, 0, \irqstat, c0, c0, 0 @ ICIP diff --git a/include/asm-arm/arch-realview/entry-macro.S b/include/asm-arm/arch-realview/entry-macro.S index 1a6eec86bd47..138838d4ad75 100644 --- a/include/asm-arm/arch-realview/entry-macro.S +++ b/include/asm-arm/arch-realview/entry-macro.S @@ -13,6 +13,12 @@ .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: diff --git a/include/asm-arm/arch-rpc/entry-macro.S b/include/asm-arm/arch-rpc/entry-macro.S index c9e5395e5106..0cfb89b229d1 100644 --- a/include/asm-arm/arch-rpc/entry-macro.S +++ b/include/asm-arm/arch-rpc/entry-macro.S @@ -1,3 +1,8 @@ #include #include + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm diff --git a/include/asm-arm/arch-s3c2410/entry-macro.S b/include/asm-arm/arch-s3c2410/entry-macro.S index 1eb4e6b8d249..bbec0a8ff158 100644 --- a/include/asm-arm/arch-s3c2410/entry-macro.S +++ b/include/asm-arm/arch-s3c2410/entry-macro.S @@ -22,6 +22,12 @@ #include #include + .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 diff --git a/include/asm-arm/arch-sa1100/entry-macro.S b/include/asm-arm/arch-sa1100/entry-macro.S index 51fb50ce1169..028967629340 100644 --- a/include/asm-arm/arch-sa1100/entry-macro.S +++ b/include/asm-arm/arch-sa1100/entry-macro.S @@ -11,6 +11,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 mov r4, #0xfa000000 @ ICIP = 0xfa050000 add r4, r4, #0x00050000 diff --git a/include/asm-arm/arch-shark/entry-macro.S b/include/asm-arm/arch-shark/entry-macro.S index a924f27fb8d9..82463f30f3df 100644 --- a/include/asm-arm/arch-shark/entry-macro.S +++ b/include/asm-arm/arch-shark/entry-macro.S @@ -10,6 +10,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 mov r4, #0xe0000000 diff --git a/include/asm-arm/arch-versatile/entry-macro.S b/include/asm-arm/arch-versatile/entry-macro.S index feff771c0a0a..0fae002637a0 100644 --- a/include/asm-arm/arch-versatile/entry-macro.S +++ b/include/asm-arm/arch-versatile/entry-macro.S @@ -13,6 +13,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 \base, =IO_ADDRESS(VERSATILE_VIC_BASE) ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status -- cgit v1.2.3 From 4434c5c7fd61c6713de882a2272b66f32fe7cac3 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 13 Feb 2007 17:13:04 +0100 Subject: [ARM] 4186/1: iop: remove cp6_enable/disable routines This functionality is replaced by cp6_trap Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/mach-iop13xx/irq.c | 19 ------------------- arch/arm/mach-iop13xx/time.c | 10 ---------- arch/arm/mach-iop32x/irq.c | 4 ---- arch/arm/mach-iop33x/irq.c | 12 ------------ arch/arm/plat-iop/time.c | 4 ---- include/asm-arm/arch-iop13xx/iop13xx.h | 26 -------------------------- include/asm-arm/arch-iop13xx/irqs.h | 17 ----------------- include/asm-arm/arch-iop13xx/system.h | 2 -- include/asm-arm/hardware/iop3xx.h | 27 --------------------------- 9 files changed, 121 deletions(-) diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c index 162b93214965..b2eb0b961031 100644 --- a/arch/arm/mach-iop13xx/irq.c +++ b/arch/arm/mach-iop13xx/irq.c @@ -161,65 +161,49 @@ static void write_intsize(u32 val) static void iop13xx_irq_mask0 (unsigned int irq) { - u32 cp_flags = iop13xx_cp6_save(); write_intctl_0(read_intctl_0() & ~(1 << (irq - 0))); - iop13xx_cp6_restore(cp_flags); } static void iop13xx_irq_mask1 (unsigned int irq) { - u32 cp_flags = iop13xx_cp6_save(); write_intctl_1(read_intctl_1() & ~(1 << (irq - 32))); - iop13xx_cp6_restore(cp_flags); } static void iop13xx_irq_mask2 (unsigned int irq) { - u32 cp_flags = iop13xx_cp6_save(); write_intctl_2(read_intctl_2() & ~(1 << (irq - 64))); - iop13xx_cp6_restore(cp_flags); } static void iop13xx_irq_mask3 (unsigned int irq) { - u32 cp_flags = iop13xx_cp6_save(); write_intctl_3(read_intctl_3() & ~(1 << (irq - 96))); - iop13xx_cp6_restore(cp_flags); } static void iop13xx_irq_unmask0(unsigned int irq) { - u32 cp_flags = iop13xx_cp6_save(); write_intctl_0(read_intctl_0() | (1 << (irq - 0))); - iop13xx_cp6_restore(cp_flags); } static void iop13xx_irq_unmask1(unsigned int irq) { - u32 cp_flags = iop13xx_cp6_save(); write_intctl_1(read_intctl_1() | (1 << (irq - 32))); - iop13xx_cp6_restore(cp_flags); } static void iop13xx_irq_unmask2(unsigned int irq) { - u32 cp_flags = iop13xx_cp6_save(); write_intctl_2(read_intctl_2() | (1 << (irq - 64))); - iop13xx_cp6_restore(cp_flags); } static void iop13xx_irq_unmask3(unsigned int irq) { - u32 cp_flags = iop13xx_cp6_save(); write_intctl_3(read_intctl_3() | (1 << (irq - 96))); - iop13xx_cp6_restore(cp_flags); } static struct irq_chip iop13xx_irqchip1 = { @@ -256,7 +240,6 @@ void __init iop13xx_init_irq(void) { unsigned int i; - u32 cp_flags = iop13xx_cp6_save(); iop_init_cp6_handler(); /* disable all interrupts */ @@ -288,6 +271,4 @@ void __init iop13xx_init_irq(void) set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } - - iop13xx_cp6_restore(cp_flags); } diff --git a/arch/arm/mach-iop13xx/time.c b/arch/arm/mach-iop13xx/time.c index 8b21365f653f..fc9d9d9a8429 100644 --- a/arch/arm/mach-iop13xx/time.c +++ b/arch/arm/mach-iop13xx/time.c @@ -38,11 +38,8 @@ static inline u32 read_tcr1(void) unsigned long iop13xx_gettimeoffset(void) { unsigned long offset; - u32 cp_flags; - cp_flags = iop13xx_cp6_save(); offset = next_jiffy_time - read_tcr1(); - iop13xx_cp6_restore(cp_flags); return offset / ticks_per_usec; } @@ -50,8 +47,6 @@ unsigned long iop13xx_gettimeoffset(void) static irqreturn_t iop13xx_timer_interrupt(int irq, void *dev_id) { - u32 cp_flags = iop13xx_cp6_save(); - write_seqlock(&xtime_lock); asm volatile("mcr p6, 0, %0, c6, c9, 0" : : "r" (1)); @@ -64,8 +59,6 @@ iop13xx_timer_interrupt(int irq, void *dev_id) write_sequnlock(&xtime_lock); - iop13xx_cp6_restore(cp_flags); - return IRQ_HANDLED; } @@ -78,7 +71,6 @@ static struct irqaction iop13xx_timer_irq = { void __init iop13xx_init_time(unsigned long tick_rate) { u32 timer_ctl; - u32 cp_flags; ticks_per_jiffy = (tick_rate + HZ/2) / HZ; ticks_per_usec = tick_rate / 1000000; @@ -91,12 +83,10 @@ void __init iop13xx_init_time(unsigned long tick_rate) * We use timer 0 for our timer interrupt, and timer 1 as * monotonic counter for tracking missed jiffies. */ - cp_flags = iop13xx_cp6_save(); asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (ticks_per_jiffy - 1)); asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (timer_ctl)); asm volatile("mcr p6, 0, %0, c5, c9, 0" : : "r" (0xffffffff)); asm volatile("mcr p6, 0, %0, c1, c9, 0" : : "r" (timer_ctl)); - iop13xx_cp6_restore(cp_flags); setup_irq(IRQ_IOP13XX_TIMER0, &iop13xx_timer_irq); } diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c index 8b0ac5590ae4..82598dc18d80 100644 --- a/arch/arm/mach-iop32x/irq.c +++ b/arch/arm/mach-iop32x/irq.c @@ -23,16 +23,12 @@ static u32 iop32x_mask; static inline void intctl_write(u32 val) { - iop3xx_cp6_enable(); asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); } static inline void intstr_write(u32 val) { - iop3xx_cp6_enable(); asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); } static void diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c index effbe6b782d0..c65ea78a2427 100644 --- a/arch/arm/mach-iop33x/irq.c +++ b/arch/arm/mach-iop33x/irq.c @@ -24,44 +24,32 @@ static u32 iop33x_mask1; static inline void intctl0_write(u32 val) { - iop3xx_cp6_enable(); asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); } static inline void intctl1_write(u32 val) { - iop3xx_cp6_enable(); asm volatile("mcr p6, 0, %0, c1, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); } static inline void intstr0_write(u32 val) { - iop3xx_cp6_enable(); asm volatile("mcr p6, 0, %0, c2, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); } static inline void intstr1_write(u32 val) { - iop3xx_cp6_enable(); asm volatile("mcr p6, 0, %0, c3, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); } static inline void intbase_write(u32 val) { - iop3xx_cp6_enable(); asm volatile("mcr p6, 0, %0, c12, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); } static inline void intsize_write(u32 val) { - iop3xx_cp6_enable(); asm volatile("mcr p6, 0, %0, c13, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); } static void diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c index f530abdaa7a1..0d53b813cbb4 100644 --- a/arch/arm/plat-iop/time.c +++ b/arch/arm/plat-iop/time.c @@ -51,9 +51,7 @@ iop3xx_timer_interrupt(int irq, void *dev_id) { write_seqlock(&xtime_lock); - iop3xx_cp6_enable(); asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (1)); - iop3xx_cp6_disable(); while ((signed long)(next_jiffy_time - *IOP3XX_TU_TCR1) >= ticks_per_jiffy) { @@ -87,12 +85,10 @@ void __init iop3xx_init_time(unsigned long tick_rate) * We use timer 0 for our timer interrupt, and timer 1 as * monotonic counter for tracking missed jiffies. */ - iop3xx_cp6_enable(); asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (ticks_per_jiffy - 1)); asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); asm volatile("mcr p6, 0, %0, c5, c1, 0" : : "r" (0xffffffff)); asm volatile("mcr p6, 0, %0, c1, c1, 0" : : "r" (timer_ctl)); - iop3xx_cp6_disable(); setup_irq(IRQ_IOP3XX_TIMER0, &iop3xx_timer_irq); } diff --git a/include/asm-arm/arch-iop13xx/iop13xx.h b/include/asm-arm/arch-iop13xx/iop13xx.h index a88522a0ff8e..e7430593d6fb 100644 --- a/include/asm-arm/arch-iop13xx/iop13xx.h +++ b/include/asm-arm/arch-iop13xx/iop13xx.h @@ -12,32 +12,6 @@ void iop13xx_init_irq(void); void iop13xx_init_time(unsigned long tickrate); unsigned long iop13xx_gettimeoffset(void); -/* handle cp6 access - * to do: handle access in entry-armv5.S and unify with - * the iop3xx implementation - * note: use iop13xx_cp6_enable_irq_save and iop13xx_cp6_irq_restore (irq.h) - * when interrupts are enabled - */ -static inline unsigned long iop13xx_cp6_save(void) -{ - u32 temp, cp_flags; - - asm volatile ( - "mrc p15, 0, %1, c15, c1, 0\n\t" - "orr %0, %1, #(1 << 6)\n\t" - "mcr p15, 0, %0, c15, c1, 0\n\t" - : "=r" (temp), "=r"(cp_flags)); - - return cp_flags; -} - -static inline void iop13xx_cp6_restore(unsigned long cp_flags) -{ - asm volatile ( - "mcr p15, 0, %0, c15, c1, 0\n\t" - : : "r" (cp_flags) ); -} - /* CPUID CP6 R0 Page 0 */ static inline int iop13xx_cpu_id(void) { diff --git a/include/asm-arm/arch-iop13xx/irqs.h b/include/asm-arm/arch-iop13xx/irqs.h index 442e35a40359..5c6fac2a4004 100644 --- a/include/asm-arm/arch-iop13xx/irqs.h +++ b/include/asm-arm/arch-iop13xx/irqs.h @@ -3,8 +3,6 @@ #ifndef __ASSEMBLER__ #include -#include /* local_irq_save */ -#include /* iop13xx_cp6_* */ /* INTPND0 CP6 R0 Page 3 */ @@ -41,21 +39,6 @@ static inline u32 read_intpnd_3(void) asm volatile("mrc p6, 0, %0, c3, c3, 0":"=r" (val)); return val; } - -static inline void -iop13xx_cp6_enable_irq_save(unsigned long *cp_flags, unsigned long *irq_flags) -{ - local_irq_save(*irq_flags); - *cp_flags = iop13xx_cp6_save(); -} - -static inline void -iop13xx_cp6_irq_restore(unsigned long *cp_flags, - unsigned long *irq_flags) -{ - iop13xx_cp6_restore(*cp_flags); - local_irq_restore(*irq_flags); -} #endif #define INTBASE 0 diff --git a/include/asm-arm/arch-iop13xx/system.h b/include/asm-arm/arch-iop13xx/system.h index ee3a62530af2..127827058e1f 100644 --- a/include/asm-arm/arch-iop13xx/system.h +++ b/include/asm-arm/arch-iop13xx/system.h @@ -48,12 +48,10 @@ static inline void arch_reset(char mode) /* * Reset the internal bus (warning both cores are reset) */ - u32 cp_flags = iop13xx_cp6_save(); write_wdtcr(IOP13XX_WDTCR_EN_ARM); write_wdtcr(IOP13XX_WDTCR_EN); write_wdtsr(IOP13XX_WDTSR_WRITE_EN | IOP13XX_WDTCR_IB_RESET); write_wdtcr(0x1000); - iop13xx_cp6_restore(cp_flags); for(;;); } diff --git a/include/asm-arm/hardware/iop3xx.h b/include/asm-arm/hardware/iop3xx.h index c91b546e20ef..47fcbf6f52d3 100644 --- a/include/asm-arm/hardware/iop3xx.h +++ b/include/asm-arm/hardware/iop3xx.h @@ -283,33 +283,6 @@ void iop_init_cp6_handler(void); extern struct platform_device iop3xx_i2c0_device; extern struct platform_device iop3xx_i2c1_device; -extern inline void iop3xx_cp6_enable(void) -{ - u32 temp; - - asm volatile ( - "mrc p15, 0, %0, c15, c1, 0\n\t" - "orr %0, %0, #(1 << 6)\n\t" - "mcr p15, 0, %0, c15, c1, 0\n\t" - "mrc p15, 0, %0, c15, c1, 0\n\t" - "mov %0, %0\n\t" - "sub pc, pc, #4\n\t" - : "=r" (temp) ); -} - -extern inline void iop3xx_cp6_disable(void) -{ - u32 temp; - - asm volatile ( - "mrc p15, 0, %0, c15, c1, 0\n\t" - "bic %0, %0, #(1 << 6)\n\t" - "mcr p15, 0, %0, c15, c1, 0\n\t" - "mrc p15, 0, %0, c15, c1, 0\n\t" - "mov %0, %0\n\t" - "sub pc, pc, #4\n\t" - : "=r" (temp) ); -} #endif -- cgit v1.2.3 From 3668b45d46f777b0773ef5ff49531c1144efb6dd Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 13 Feb 2007 17:13:34 +0100 Subject: [ARM] 4187/1: iop: unify time implementation across iop32x, iop33x, and iop13xx * architecture specific details are handled in asm/arch/time.h * ARCH_IOP13XX now selects PLAT_IOP * as suggested by Lennert use ifdef CONFIG_XSCALE to skip the cp_wait on XSC3 Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/mach-iop13xx/Makefile | 1 - arch/arm/mach-iop13xx/iq81340mc.c | 5 +- arch/arm/mach-iop13xx/iq81340sc.c | 5 +- arch/arm/mach-iop13xx/time.c | 92 ---------------------------------- arch/arm/mach-iop32x/glantank.c | 5 +- arch/arm/mach-iop32x/iq31244.c | 8 +-- arch/arm/mach-iop32x/iq80321.c | 5 +- arch/arm/mach-iop32x/n2100.c | 5 +- arch/arm/mach-iop33x/iq80331.c | 7 +-- arch/arm/mach-iop33x/iq80332.c | 7 +-- arch/arm/plat-iop/Makefile | 1 + arch/arm/plat-iop/time.c | 60 ++++++++++++---------- include/asm-arm/arch-iop13xx/iop13xx.h | 12 ----- include/asm-arm/arch-iop13xx/time.h | 51 +++++++++++++++++++ include/asm-arm/arch-iop32x/time.h | 4 ++ include/asm-arm/arch-iop33x/time.h | 4 ++ include/asm-arm/hardware/iop3xx.h | 55 ++++++++++++++++---- 17 files changed, 166 insertions(+), 161 deletions(-) delete mode 100644 arch/arm/mach-iop13xx/time.c create mode 100644 include/asm-arm/arch-iop13xx/time.h create mode 100644 include/asm-arm/arch-iop32x/time.h create mode 100644 include/asm-arm/arch-iop33x/time.h diff --git a/arch/arm/mach-iop13xx/Makefile b/arch/arm/mach-iop13xx/Makefile index c3d6c08f2d4c..4185e0586c33 100644 --- a/arch/arm/mach-iop13xx/Makefile +++ b/arch/arm/mach-iop13xx/Makefile @@ -5,7 +5,6 @@ obj- := obj-$(CONFIG_ARCH_IOP13XX) += setup.o obj-$(CONFIG_ARCH_IOP13XX) += irq.o -obj-$(CONFIG_ARCH_IOP13XX) += time.o obj-$(CONFIG_ARCH_IOP13XX) += pci.o obj-$(CONFIG_ARCH_IOP13XX) += io.o obj-$(CONFIG_MACH_IQ81340SC) += iq81340sc.o diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c index 2a1bbfe9896f..a519d707571c 100644 --- a/arch/arm/mach-iop13xx/iq81340mc.c +++ b/arch/arm/mach-iop13xx/iq81340mc.c @@ -25,6 +25,7 @@ #include #include #include +#include extern int init_atu; /* Flag to select which ATU(s) to initialize / disable */ @@ -78,12 +79,12 @@ static void __init iq81340mc_init(void) static void __init iq81340mc_timer_init(void) { - iop13xx_init_time(400000000); + iop_init_time(400000000); } static struct sys_timer iq81340mc_timer = { .init = iq81340mc_timer_init, - .offset = iop13xx_gettimeoffset, + .offset = iop_gettimeoffset, }; MACHINE_START(IQ81340MC, "Intel IQ81340MC") diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c index 5ad2b62c9bfd..0e71fbcabe00 100644 --- a/arch/arm/mach-iop13xx/iq81340sc.c +++ b/arch/arm/mach-iop13xx/iq81340sc.c @@ -25,6 +25,7 @@ #include #include #include +#include extern int init_atu; @@ -80,12 +81,12 @@ static void __init iq81340sc_init(void) static void __init iq81340sc_timer_init(void) { - iop13xx_init_time(400000000); + iop_init_time(400000000); } static struct sys_timer iq81340sc_timer = { .init = iq81340sc_timer_init, - .offset = iop13xx_gettimeoffset, + .offset = iop_gettimeoffset, }; MACHINE_START(IQ81340SC, "Intel IQ81340SC") diff --git a/arch/arm/mach-iop13xx/time.c b/arch/arm/mach-iop13xx/time.c deleted file mode 100644 index fc9d9d9a8429..000000000000 --- a/arch/arm/mach-iop13xx/time.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * arch/arm/mach-iop13xx/time.c - * - * Timer code for IOP13xx (copied from IOP32x/IOP33x implementation) - * - * Author: Deepak Saxena - * - * Copyright 2002-2003 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned long ticks_per_jiffy; -static unsigned long ticks_per_usec; -static unsigned long next_jiffy_time; - -static inline u32 read_tcr1(void) -{ - u32 val; - asm volatile("mrc p6, 0, %0, c3, c9, 0" : "=r" (val)); - return val; -} - -unsigned long iop13xx_gettimeoffset(void) -{ - unsigned long offset; - - offset = next_jiffy_time - read_tcr1(); - - return offset / ticks_per_usec; -} - -static irqreturn_t -iop13xx_timer_interrupt(int irq, void *dev_id) -{ - write_seqlock(&xtime_lock); - - asm volatile("mcr p6, 0, %0, c6, c9, 0" : : "r" (1)); - - while ((signed long)(next_jiffy_time - read_tcr1()) - >= ticks_per_jiffy) { - timer_tick(); - next_jiffy_time -= ticks_per_jiffy; - } - - write_sequnlock(&xtime_lock); - - return IRQ_HANDLED; -} - -static struct irqaction iop13xx_timer_irq = { - .name = "IOP13XX Timer Tick", - .handler = iop13xx_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, -}; - -void __init iop13xx_init_time(unsigned long tick_rate) -{ - u32 timer_ctl; - - ticks_per_jiffy = (tick_rate + HZ/2) / HZ; - ticks_per_usec = tick_rate / 1000000; - next_jiffy_time = 0xffffffff; - - timer_ctl = IOP13XX_TMR_EN | IOP13XX_TMR_PRIVILEGED | - IOP13XX_TMR_RELOAD | IOP13XX_TMR_RATIO_1_1; - - /* - * We use timer 0 for our timer interrupt, and timer 1 as - * monotonic counter for tracking missed jiffies. - */ - asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (ticks_per_jiffy - 1)); - asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (timer_ctl)); - asm volatile("mcr p6, 0, %0, c5, c9, 0" : : "r" (0xffffffff)); - asm volatile("mcr p6, 0, %0, c1, c9, 0" : : "r" (timer_ctl)); - - setup_irq(IRQ_IOP13XX_TIMER0, &iop13xx_timer_irq); -} diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c index b9b765057dbe..45f4f13ae11b 100644 --- a/arch/arm/mach-iop32x/glantank.c +++ b/arch/arm/mach-iop32x/glantank.c @@ -31,6 +31,7 @@ #include #include #include +#include /* * GLAN Tank timer tick configuration. @@ -38,12 +39,12 @@ static void __init glantank_timer_init(void) { /* 33.333 MHz crystal. */ - iop3xx_init_time(200000000); + iop_init_time(200000000); } static struct sys_timer glantank_timer = { .init = glantank_timer_init, - .offset = iop3xx_gettimeoffset, + .offset = iop_gettimeoffset, }; diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c index be4aedfa0de6..571ac35bc2c7 100644 --- a/arch/arm/mach-iop32x/iq31244.c +++ b/arch/arm/mach-iop32x/iq31244.c @@ -36,7 +36,7 @@ #include #include #include - +#include /* * The EP80219 and IQ31244 use the same machine ID. To find out @@ -56,16 +56,16 @@ static void __init iq31244_timer_init(void) { if (is_80219()) { /* 33.333 MHz crystal. */ - iop3xx_init_time(200000000); + iop_init_time(200000000); } else { /* 33.000 MHz crystal. */ - iop3xx_init_time(198000000); + iop_init_time(198000000); } } static struct sys_timer iq31244_timer = { .init = iq31244_timer_init, - .offset = iop3xx_gettimeoffset, + .offset = iop_gettimeoffset, }; diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c index 1f37b5501888..361c70c0f64c 100644 --- a/arch/arm/mach-iop32x/iq80321.c +++ b/arch/arm/mach-iop32x/iq80321.c @@ -33,6 +33,7 @@ #include #include #include +#include /* * IQ80321 timer tick configuration. @@ -40,12 +41,12 @@ static void __init iq80321_timer_init(void) { /* 33.333 MHz crystal. */ - iop3xx_init_time(200000000); + iop_init_time(200000000); } static struct sys_timer iq80321_timer = { .init = iq80321_timer_init, - .offset = iop3xx_gettimeoffset, + .offset = iop_gettimeoffset, }; diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c index 2499a7707e3c..92fa0c55443e 100644 --- a/arch/arm/mach-iop32x/n2100.c +++ b/arch/arm/mach-iop32x/n2100.c @@ -37,6 +37,7 @@ #include #include #include +#include /* * N2100 timer tick configuration. @@ -44,12 +45,12 @@ static void __init n2100_timer_init(void) { /* 33.000 MHz crystal. */ - iop3xx_init_time(198000000); + iop_init_time(198000000); } static struct sys_timer n2100_timer = { .init = n2100_timer_init, - .offset = iop3xx_gettimeoffset, + .offset = iop_gettimeoffset, }; diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c index 97a7b7488264..1a9e36138d80 100644 --- a/arch/arm/mach-iop33x/iq80331.c +++ b/arch/arm/mach-iop33x/iq80331.c @@ -32,6 +32,7 @@ #include #include #include +#include /* * IQ80331 timer tick configuration. @@ -40,14 +41,14 @@ static void __init iq80331_timer_init(void) { /* D-Step parts run at a higher internal bus frequency */ if (*IOP3XX_ATURID >= 0xa) - iop3xx_init_time(333000000); + iop_init_time(333000000); else - iop3xx_init_time(266000000); + iop_init_time(266000000); } static struct sys_timer iq80331_timer = { .init = iq80331_timer_init, - .offset = iop3xx_gettimeoffset, + .offset = iop_gettimeoffset, }; diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c index 9887bfc1c078..96d6f0f3cd21 100644 --- a/arch/arm/mach-iop33x/iq80332.c +++ b/arch/arm/mach-iop33x/iq80332.c @@ -32,6 +32,7 @@ #include #include #include +#include /* * IQ80332 timer tick configuration. @@ -40,14 +41,14 @@ static void __init iq80332_timer_init(void) { /* D-Step parts and the iop333 run at a higher internal bus frequency */ if (*IOP3XX_ATURID >= 0xa || *IOP3XX_ATUDID == 0x374) - iop3xx_init_time(333000000); + iop_init_time(333000000); else - iop3xx_init_time(266000000); + iop_init_time(266000000); } static struct sys_timer iq80332_timer = { .init = iq80332_timer_init, - .offset = iop3xx_gettimeoffset, + .offset = iop_gettimeoffset, }; diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile index 3250d732a171..4d2b1da3cd82 100644 --- a/arch/arm/plat-iop/Makefile +++ b/arch/arm/plat-iop/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_ARCH_IOP33X) += cp6.o # IOP13XX obj-$(CONFIG_ARCH_IOP13XX) += cp6.o +obj-$(CONFIG_ARCH_IOP13XX) += time.o obj-m := obj-n := diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c index 0d53b813cbb4..16300adfb4de 100644 --- a/arch/arm/plat-iop/time.c +++ b/arch/arm/plat-iop/time.c @@ -24,37 +24,45 @@ #include #include #include - -#ifdef CONFIG_ARCH_IOP32X -#define IRQ_IOP3XX_TIMER0 IRQ_IOP32X_TIMER0 -#else -#ifdef CONFIG_ARCH_IOP33X -#define IRQ_IOP3XX_TIMER0 IRQ_IOP33X_TIMER0 -#endif -#endif +#include static unsigned long ticks_per_jiffy; static unsigned long ticks_per_usec; static unsigned long next_jiffy_time; -unsigned long iop3xx_gettimeoffset(void) +unsigned long iop_gettimeoffset(void) { - unsigned long offset; + unsigned long offset, temp1, temp2; + + /* enable cp6, if necessary, to avoid taking the overhead of an + * undefined instruction trap + */ + asm volatile ( + "mrc p15, 0, %0, c15, c1, 0\n\t" + "ands %1, %0, #(1 << 6)\n\t" + "orreq %0, %0, #(1 << 6)\n\t" + "mcreq p15, 0, %0, c15, c1, 0\n\t" +#ifdef CONFIG_XSCALE + "mrceq p15, 0, %0, c15, c1, 0\n\t" + "moveq %0, %0\n\t" + "subeq pc, pc, #4\n\t" +#endif + : "=r"(temp1), "=r"(temp2) : : "cc"); - offset = next_jiffy_time - *IOP3XX_TU_TCR1; + offset = next_jiffy_time - read_tcr1(); return offset / ticks_per_usec; } static irqreturn_t -iop3xx_timer_interrupt(int irq, void *dev_id) +iop_timer_interrupt(int irq, void *dev_id) { write_seqlock(&xtime_lock); - asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (1)); + write_tisr(1); - while ((signed long)(next_jiffy_time - *IOP3XX_TU_TCR1) - >= ticks_per_jiffy) { + while ((signed long)(next_jiffy_time - read_tcr1()) + >= ticks_per_jiffy) { timer_tick(); next_jiffy_time -= ticks_per_jiffy; } @@ -64,13 +72,13 @@ iop3xx_timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct irqaction iop3xx_timer_irq = { - .name = "IOP3XX Timer Tick", - .handler = iop3xx_timer_interrupt, +static struct irqaction iop_timer_irq = { + .name = "IOP Timer Tick", + .handler = iop_timer_interrupt, .flags = IRQF_DISABLED | IRQF_TIMER, }; -void __init iop3xx_init_time(unsigned long tick_rate) +void __init iop_init_time(unsigned long tick_rate) { u32 timer_ctl; @@ -78,17 +86,17 @@ void __init iop3xx_init_time(unsigned long tick_rate) ticks_per_usec = tick_rate / 1000000; next_jiffy_time = 0xffffffff; - timer_ctl = IOP3XX_TMR_EN | IOP3XX_TMR_PRIVILEGED | - IOP3XX_TMR_RELOAD | IOP3XX_TMR_RATIO_1_1; + timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED | + IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1; /* * We use timer 0 for our timer interrupt, and timer 1 as * monotonic counter for tracking missed jiffies. */ - asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (ticks_per_jiffy - 1)); - asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); - asm volatile("mcr p6, 0, %0, c5, c1, 0" : : "r" (0xffffffff)); - asm volatile("mcr p6, 0, %0, c1, c1, 0" : : "r" (timer_ctl)); + write_trr0(ticks_per_jiffy - 1); + write_tmr0(timer_ctl); + write_trr1(0xffffffff); + write_tmr1(timer_ctl); - setup_irq(IRQ_IOP3XX_TIMER0, &iop3xx_timer_irq); + setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq); } diff --git a/include/asm-arm/arch-iop13xx/iop13xx.h b/include/asm-arm/arch-iop13xx/iop13xx.h index e7430593d6fb..d26b755a9879 100644 --- a/include/asm-arm/arch-iop13xx/iop13xx.h +++ b/include/asm-arm/arch-iop13xx/iop13xx.h @@ -9,8 +9,6 @@ void iop13xx_init_irq(void); void iop13xx_map_io(void); void iop13xx_platform_init(void); void iop13xx_init_irq(void); -void iop13xx_init_time(unsigned long tickrate); -unsigned long iop13xx_gettimeoffset(void); /* CPUID CP6 R0 Page 0 */ static inline int iop13xx_cpu_id(void) @@ -453,14 +451,4 @@ static inline int iop13xx_cpu_id(void) #define IOP13XX_PBI_BAR1 IOP13XX_PBI_OFFSET(0x10) #define IOP13XX_PBI_LR1 IOP13XX_PBI_OFFSET(0x14) -#define IOP13XX_TMR_TC 0x01 -#define IOP13XX_TMR_EN 0x02 -#define IOP13XX_TMR_RELOAD 0x04 -#define IOP13XX_TMR_PRIVILEGED 0x08 - -#define IOP13XX_TMR_RATIO_1_1 0x00 -#define IOP13XX_TMR_RATIO_4_1 0x10 -#define IOP13XX_TMR_RATIO_8_1 0x20 -#define IOP13XX_TMR_RATIO_16_1 0x30 - #endif /* _IOP13XX_HW_H_ */ diff --git a/include/asm-arm/arch-iop13xx/time.h b/include/asm-arm/arch-iop13xx/time.h new file mode 100644 index 000000000000..77a837a02dec --- /dev/null +++ b/include/asm-arm/arch-iop13xx/time.h @@ -0,0 +1,51 @@ +#ifndef _IOP13XX_TIME_H_ +#define _IOP13XX_TIME_H_ +#define IRQ_IOP_TIMER0 IRQ_IOP13XX_TIMER0 + +#define IOP_TMR_EN 0x02 +#define IOP_TMR_RELOAD 0x04 +#define IOP_TMR_PRIVILEGED 0x08 +#define IOP_TMR_RATIO_1_1 0x00 + +void iop_init_time(unsigned long tickrate); +unsigned long iop_gettimeoffset(void); + +static inline void write_tmr0(u32 val) +{ + asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (val)); +} + +static inline void write_tmr1(u32 val) +{ + asm volatile("mcr p6, 0, %0, c1, c9, 0" : : "r" (val)); +} + +static inline u32 read_tcr0(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c2, c9, 0" : "=r" (val)); + return val; +} + +static inline u32 read_tcr1(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c3, c9, 0" : "=r" (val)); + return val; +} + +static inline void write_trr0(u32 val) +{ + asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (val)); +} + +static inline void write_trr1(u32 val) +{ + asm volatile("mcr p6, 0, %0, c5, c9, 0" : : "r" (val)); +} + +static inline void write_tisr(u32 val) +{ + asm volatile("mcr p6, 0, %0, c6, c9, 0" : : "r" (val)); +} +#endif diff --git a/include/asm-arm/arch-iop32x/time.h b/include/asm-arm/arch-iop32x/time.h new file mode 100644 index 000000000000..0f28c9949623 --- /dev/null +++ b/include/asm-arm/arch-iop32x/time.h @@ -0,0 +1,4 @@ +#ifndef _IOP32X_TIME_H_ +#define _IOP32X_TIME_H_ +#define IRQ_IOP_TIMER0 IRQ_IOP32X_TIMER0 +#endif diff --git a/include/asm-arm/arch-iop33x/time.h b/include/asm-arm/arch-iop33x/time.h new file mode 100644 index 000000000000..4ac4d7664f85 --- /dev/null +++ b/include/asm-arm/arch-iop33x/time.h @@ -0,0 +1,4 @@ +#ifndef _IOP33X_TIME_H_ +#define _IOP33X_TIME_H_ +#define IRQ_IOP_TIMER0 IRQ_IOP33X_TIMER0 +#endif diff --git a/include/asm-arm/hardware/iop3xx.h b/include/asm-arm/hardware/iop3xx.h index 47fcbf6f52d3..15141a9caca8 100644 --- a/include/asm-arm/hardware/iop3xx.h +++ b/include/asm-arm/hardware/iop3xx.h @@ -188,14 +188,10 @@ extern void gpio_line_set(int line, int value); #define IOP3XX_TU_TRR1 (volatile u32 *)IOP3XX_TIMER_REG(0x0014) #define IOP3XX_TU_TISR (volatile u32 *)IOP3XX_TIMER_REG(0x0018) #define IOP3XX_TU_WDTCR (volatile u32 *)IOP3XX_TIMER_REG(0x001c) -#define IOP3XX_TMR_TC 0x01 -#define IOP3XX_TMR_EN 0x02 -#define IOP3XX_TMR_RELOAD 0x04 -#define IOP3XX_TMR_PRIVILEGED 0x09 -#define IOP3XX_TMR_RATIO_1_1 0x00 -#define IOP3XX_TMR_RATIO_4_1 0x10 -#define IOP3XX_TMR_RATIO_8_1 0x20 -#define IOP3XX_TMR_RATIO_16_1 0x30 +#define IOP_TMR_EN 0x02 +#define IOP_TMR_RELOAD 0x04 +#define IOP_TMR_PRIVILEGED 0x08 +#define IOP_TMR_RATIO_1_1 0x00 /* Application accelerator unit */ #define IOP3XX_AAU_ACR (volatile u32 *)IOP3XX_REG_ADDR(0x0800) @@ -276,9 +272,48 @@ extern void gpio_line_set(int line, int value); #ifndef __ASSEMBLY__ void iop3xx_map_io(void); -void iop3xx_init_time(unsigned long); -unsigned long iop3xx_gettimeoffset(void); void iop_init_cp6_handler(void); +void iop_init_time(unsigned long tickrate); +unsigned long iop_gettimeoffset(void); + +static inline void write_tmr0(u32 val) +{ + asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (val)); +} + +static inline void write_tmr1(u32 val) +{ + asm volatile("mcr p6, 0, %0, c1, c1, 0" : : "r" (val)); +} + +static inline u32 read_tcr0(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c2, c1, 0" : "=r" (val)); + return val; +} + +static inline u32 read_tcr1(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c3, c1, 0" : "=r" (val)); + return val; +} + +static inline void write_trr0(u32 val) +{ + asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (val)); +} + +static inline void write_trr1(u32 val) +{ + asm volatile("mcr p6, 0, %0, c5, c1, 0" : : "r" (val)); +} + +static inline void write_tisr(u32 val) +{ + asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (val)); +} extern struct platform_device iop3xx_i2c0_device; extern struct platform_device iop3xx_i2c1_device; -- cgit v1.2.3