![Arnd Bergmann](/assets/img/avatar_default.png)
The head-v7.S contains a call to the generic cpu_suspend function, which is only available when selected by the i.MX6 code. As pointed out by Shawn Guo, i.MX5 does not actually use any functions defined in head-v7.S. It is also needed only for the i.MX6 power management code and for the SMP code, so we can restrict building this file to situations in which at least one of those two is present. Finally, other platforms with a similar file call it headsmp.S, so we can rename it to the same for consistency. Without this patch, building imx5 standalone results in: arch/arm/mach-imx/built-in.o: In function `v7_cpu_resume': arch/arm/mach-imx/head-v7.S:104: undefined reference to `cpu_resume' Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Shawn Guo <shawn.guo@linaro.org> Cc: Eric Miao <eric.miao@linaro.org> Cc: stable@vger.kernel.org
107 lines
2.7 KiB
ArmAsm
107 lines
2.7 KiB
ArmAsm
/*
|
|
* Copyright 2011 Freescale Semiconductor, Inc.
|
|
* Copyright 2011 Linaro Ltd.
|
|
*
|
|
* The code contained herein is licensed under the GNU General Public
|
|
* License. You may obtain a copy of the GNU General Public License
|
|
* Version 2 or later at the following locations:
|
|
*
|
|
* http://www.opensource.org/licenses/gpl-license.html
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*/
|
|
|
|
#include <linux/linkage.h>
|
|
#include <linux/init.h>
|
|
#include <asm/asm-offsets.h>
|
|
#include <asm/hardware/cache-l2x0.h>
|
|
|
|
.section ".text.head", "ax"
|
|
|
|
/*
|
|
* The secondary kernel init calls v7_flush_dcache_all before it enables
|
|
* the L1; however, the L1 comes out of reset in an undefined state, so
|
|
* the clean + invalidate performed by v7_flush_dcache_all causes a bunch
|
|
* of cache lines with uninitialized data and uninitialized tags to get
|
|
* written out to memory, which does really unpleasant things to the main
|
|
* processor. We fix this by performing an invalidate, rather than a
|
|
* clean + invalidate, before jumping into the kernel.
|
|
*
|
|
* This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
|
|
* to be called for both secondary cores startup and primary core resume
|
|
* procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S.
|
|
*/
|
|
ENTRY(v7_invalidate_l1)
|
|
mov r0, #0
|
|
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
|
|
mcr p15, 2, r0, c0, c0, 0
|
|
mrc p15, 1, r0, c0, c0, 0
|
|
|
|
ldr r1, =0x7fff
|
|
and r2, r1, r0, lsr #13
|
|
|
|
ldr r1, =0x3ff
|
|
|
|
and r3, r1, r0, lsr #3 @ NumWays - 1
|
|
add r2, r2, #1 @ NumSets
|
|
|
|
and r0, r0, #0x7
|
|
add r0, r0, #4 @ SetShift
|
|
|
|
clz r1, r3 @ WayShift
|
|
add r4, r3, #1 @ NumWays
|
|
1: sub r2, r2, #1 @ NumSets--
|
|
mov r3, r4 @ Temp = NumWays
|
|
2: subs r3, r3, #1 @ Temp--
|
|
mov r5, r3, lsl r1
|
|
mov r6, r2, lsl r0
|
|
orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
|
|
mcr p15, 0, r5, c7, c6, 2
|
|
bgt 2b
|
|
cmp r2, #0
|
|
bgt 1b
|
|
dsb
|
|
isb
|
|
mov pc, lr
|
|
ENDPROC(v7_invalidate_l1)
|
|
|
|
#ifdef CONFIG_SMP
|
|
ENTRY(v7_secondary_startup)
|
|
bl v7_invalidate_l1
|
|
b secondary_startup
|
|
ENDPROC(v7_secondary_startup)
|
|
#endif
|
|
|
|
#ifdef CONFIG_PM
|
|
/*
|
|
* The following code is located into the .data section. This is to
|
|
* allow phys_l2x0_saved_regs to be accessed with a relative load
|
|
* as we are running on physical address here.
|
|
*/
|
|
.data
|
|
.align
|
|
|
|
#ifdef CONFIG_CACHE_L2X0
|
|
.macro pl310_resume
|
|
ldr r2, phys_l2x0_saved_regs
|
|
ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0
|
|
ldr r1, [r2, #L2X0_R_AUX_CTRL] @ get aux_ctrl value
|
|
str r1, [r0, #L2X0_AUX_CTRL] @ restore aux_ctrl
|
|
mov r1, #0x1
|
|
str r1, [r0, #L2X0_CTRL] @ re-enable L2
|
|
.endm
|
|
|
|
.globl phys_l2x0_saved_regs
|
|
phys_l2x0_saved_regs:
|
|
.long 0
|
|
#else
|
|
.macro pl310_resume
|
|
.endm
|
|
#endif
|
|
|
|
ENTRY(v7_cpu_resume)
|
|
bl v7_invalidate_l1
|
|
pl310_resume
|
|
b cpu_resume
|
|
ENDPROC(v7_cpu_resume)
|
|
#endif
|