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
		
			
				
	
	
		
			106 lines
		
	
	
	
		
			2.7 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			106 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
 |