From 74facffeca3795ffb5cf8898f5859fbb822e4c5d Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 2 Jun 2011 11:16:22 +0100 Subject: ARM: Allow SoCs to enable scatterlist chaining Allow SoCs to enable the scatterlist chaining support, which allows scatterlist tables to be broken up into smaller allocations. As support for this feature depends on the implementation details of the users of the scatterlists, we can't enable this globally without auditing all the users, which is a very big task. Instead, let SoCs progressively switch over to using this. SoC drivers using scatterlists and SoC DMA implementations need auditing before this option can be enabled for the SoC. Signed-off-by: Russell King --- arch/arm/Kconfig | 3 +++ arch/arm/include/asm/scatterlist.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9adc278a22ab..cc0dcbf1f6b5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -37,6 +37,9 @@ config ARM Europe. There is an ARM Linux project with a web page at . +config ARM_HAS_SG_CHAIN + bool + config HAVE_PWM bool diff --git a/arch/arm/include/asm/scatterlist.h b/arch/arm/include/asm/scatterlist.h index 2f87870d9347..cefdb8f898a1 100644 --- a/arch/arm/include/asm/scatterlist.h +++ b/arch/arm/include/asm/scatterlist.h @@ -1,6 +1,10 @@ #ifndef _ASMARM_SCATTERLIST_H #define _ASMARM_SCATTERLIST_H +#ifdef CONFIG_ARM_HAS_SG_CHAIN +#define ARCH_HAS_SG_CHAIN +#endif + #include #include #include -- cgit v1.2.3 From 37b8304642c7f91df54888955c373ae89b577fcc Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Sun, 19 Jun 2011 23:36:03 -0400 Subject: ARM: kuser: move interface documentation out of the source code Digging into some assembly file in order to get information about the kuser helpers is not that convivial. Let's move that information to a better formatted file in Documentation/arm/ and improve on it a bit. Thanks to Dave Martin for the initial cleanup and clarifications. Signed-off-by: Nicolas Pitre Acked-by: Dave Martin --- Documentation/arm/kernel_user_helpers.txt | 203 ++++++++++++++++++++++++++++++ arch/arm/kernel/entry-armv.S | 153 +--------------------- 2 files changed, 204 insertions(+), 152 deletions(-) create mode 100644 Documentation/arm/kernel_user_helpers.txt diff --git a/Documentation/arm/kernel_user_helpers.txt b/Documentation/arm/kernel_user_helpers.txt new file mode 100644 index 000000000000..0c33f72d1873 --- /dev/null +++ b/Documentation/arm/kernel_user_helpers.txt @@ -0,0 +1,203 @@ +Kernel-provided User Helpers +============================ + +These are segment of kernel provided user code reachable from user space +at a fixed address in kernel memory. This is used to provide user space +with some operations which require kernel help because of unimplemented +native feature and/or instructions in many ARM CPUs. The idea is for this +code to be executed directly in user mode for best efficiency but which is +too intimate with the kernel counter part to be left to user libraries. +In fact this code might even differ from one CPU to another depending on +the available instruction set, or whether it is a SMP systems. In other +words, the kernel reserves the right to change this code as needed without +warning. Only the entry points and their results as documented here are +guaranteed to be stable. + +This is different from (but doesn't preclude) a full blown VDSO +implementation, however a VDSO would prevent some assembly tricks with +constants that allows for efficient branching to those code segments. And +since those code segments only use a few cycles before returning to user +code, the overhead of a VDSO indirect far call would add a measurable +overhead to such minimalistic operations. + +User space is expected to bypass those helpers and implement those things +inline (either in the code emitted directly by the compiler, or part of +the implementation of a library call) when optimizing for a recent enough +processor that has the necessary native support, but only if resulting +binaries are already to be incompatible with earlier ARM processors due to +useage of similar native instructions for other things. In other words +don't make binaries unable to run on earlier processors just for the sake +of not using these kernel helpers if your compiled code is not going to +use new instructions for other purpose. + +New helpers may be added over time, so an older kernel may be missing some +helpers present in a newer kernel. For this reason, programs must check +the value of __kuser_helper_version (see below) before assuming that it is +safe to call any particular helper. This check should ideally be +performed only once at process startup time, and execution aborted early +if the required helpers are not provided by the kernel version that +process is running on. + +kuser_helper_version +-------------------- + +Location: 0xffff0ffc + +Reference declaration: + + extern int32_t __kuser_helper_version; + +Definition: + + This field contains the number of helpers being implemented by the + running kernel. User space may read this to determine the availability + of a particular helper. + +Usage example: + +#define __kuser_helper_version (*(int32_t *)0xffff0ffc) + +void check_kuser_version(void) +{ + if (__kuser_helper_version < 2) { + fprintf(stderr, "can't do atomic operations, kernel too old\n"); + abort(); + } +} + +Notes: + + User space may assume that the value of this field never changes + during the lifetime of any single process. This means that this + field can be read once during the initialisation of a library or + startup phase of a program. + +kuser_get_tls +------------- + +Location: 0xffff0fe0 + +Reference prototype: + + void * __kuser_get_tls(void); + +Input: + + lr = return address + +Output: + + r0 = TLS value + +Clobbered registers: + + none + +Definition: + + Get the TLS value as previously set via the __ARM_NR_set_tls syscall. + +Usage example: + +typedef void * (__kuser_get_tls_t)(void); +#define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0) + +void foo() +{ + void *tls = __kuser_get_tls(); + printf("TLS = %p\n", tls); +} + +Notes: + + - Valid only if __kuser_helper_version >= 1 (from kernel version 2.6.12). + +kuser_cmpxchg +------------- + +Location: 0xffff0fc0 + +Reference prototype: + + int __kuser_cmpxchg(int32_t oldval, int32_t newval, volatile int32_t *ptr); + +Input: + + r0 = oldval + r1 = newval + r2 = ptr + lr = return address + +Output: + + r0 = success code (zero or non-zero) + C flag = set if r0 == 0, clear if r0 != 0 + +Clobbered registers: + + r3, ip, flags + +Definition: + + Atomically store newval in *ptr only if *ptr is equal to oldval. + Return zero if *ptr was changed or non-zero if no exchange happened. + The C flag is also set if *ptr was changed to allow for assembly + optimization in the calling code. + +Usage example: + +typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr); +#define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0) + +int atomic_add(volatile int *ptr, int val) +{ + int old, new; + + do { + old = *ptr; + new = old + val; + } while(__kuser_cmpxchg(old, new, ptr)); + + return new; +} + +Notes: + + - This routine already includes memory barriers as needed. + + - Valid only if __kuser_helper_version >= 2 (from kernel version 2.6.12). + +kuser_memory_barrier +-------------------- + +Location: 0xffff0fa0 + +Reference prototype: + + void __kuser_memory_barrier(void); + +Input: + + lr = return address + +Output: + + none + +Clobbered registers: + + none + +Definition: + + Apply any needed memory barrier to preserve consistency with data modified + manually and __kuser_cmpxchg usage. + +Usage example: + +typedef void (__kuser_dmb_t)(void); +#define __kuser_dmb (*(__kuser_dmb_t *)0xffff0fa0) + +Notes: + + - Valid only if __kuser_helper_version >= 3 (from kernel version 2.6.15). diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index e8d885676807..63f7907c4c3c 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -754,31 +754,12 @@ ENDPROC(__switch_to) /* * User helpers. * - * These are segment of kernel provided user code reachable from user space - * at a fixed address in kernel memory. This is used to provide user space - * with some operations which require kernel help because of unimplemented - * native feature and/or instructions in many ARM CPUs. The idea is for - * this code to be executed directly in user mode for best efficiency but - * which is too intimate with the kernel counter part to be left to user - * libraries. In fact this code might even differ from one CPU to another - * depending on the available instruction set and restrictions like on - * SMP systems. In other words, the kernel reserves the right to change - * this code as needed without warning. Only the entry points and their - * results are guaranteed to be stable. - * * Each segment is 32-byte aligned and will be moved to the top of the high * vector page. New segments (if ever needed) must be added in front of * existing ones. This mechanism should be used only for things that are * really small and justified, and not be abused freely. * - * User space is expected to implement those things inline when optimizing - * for a processor that has the necessary native support, but only if such - * resulting binaries are already to be incompatible with earlier ARM - * processors due to the use of unsupported instructions other than what - * is provided here. In other words don't make binaries unable to run on - * earlier processors just for the sake of not using these kernel helpers - * if your compiled code is not going to use the new instructions for other - * purpose. + * See Documentation/arm/kernel_user_helpers.txt for formal definitions. */ THUMB( .arm ) @@ -794,98 +775,12 @@ ENDPROC(__switch_to) .globl __kuser_helper_start __kuser_helper_start: -/* - * Reference prototype: - * - * void __kernel_memory_barrier(void) - * - * Input: - * - * lr = return address - * - * Output: - * - * none - * - * Clobbered: - * - * none - * - * Definition and user space usage example: - * - * typedef void (__kernel_dmb_t)(void); - * #define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0) - * - * Apply any needed memory barrier to preserve consistency with data modified - * manually and __kuser_cmpxchg usage. - * - * This could be used as follows: - * - * #define __kernel_dmb() \ - * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \ - * : : : "r0", "lr","cc" ) - */ - __kuser_memory_barrier: @ 0xffff0fa0 smp_dmb arm usr_ret lr .align 5 -/* - * Reference prototype: - * - * int __kernel_cmpxchg(int oldval, int newval, int *ptr) - * - * Input: - * - * r0 = oldval - * r1 = newval - * r2 = ptr - * lr = return address - * - * Output: - * - * r0 = returned value (zero or non-zero) - * C flag = set if r0 == 0, clear if r0 != 0 - * - * Clobbered: - * - * r3, ip, flags - * - * Definition and user space usage example: - * - * typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr); - * #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) - * - * Atomically store newval in *ptr if *ptr is equal to oldval for user space. - * Return zero if *ptr was changed or non-zero if no exchange happened. - * The C flag is also set if *ptr was changed to allow for assembly - * optimization in the calling code. - * - * Notes: - * - * - This routine already includes memory barriers as needed. - * - * For example, a user space atomic_add implementation could look like this: - * - * #define atomic_add(ptr, val) \ - * ({ register unsigned int *__ptr asm("r2") = (ptr); \ - * register unsigned int __result asm("r1"); \ - * asm volatile ( \ - * "1: @ atomic_add\n\t" \ - * "ldr r0, [r2]\n\t" \ - * "mov r3, #0xffff0fff\n\t" \ - * "add lr, pc, #4\n\t" \ - * "add r1, r0, %2\n\t" \ - * "add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \ - * "bcc 1b" \ - * : "=&r" (__result) \ - * : "r" (__ptr), "rIL" (val) \ - * : "r0","r3","ip","lr","cc","memory" ); \ - * __result; }) - */ - __kuser_cmpxchg: @ 0xffff0fc0 #if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) @@ -959,39 +854,6 @@ kuser_cmpxchg_fixup: .align 5 -/* - * Reference prototype: - * - * int __kernel_get_tls(void) - * - * Input: - * - * lr = return address - * - * Output: - * - * r0 = TLS value - * - * Clobbered: - * - * none - * - * Definition and user space usage example: - * - * typedef int (__kernel_get_tls_t)(void); - * #define __kernel_get_tls (*(__kernel_get_tls_t *)0xffff0fe0) - * - * Get the TLS value as previously set via the __ARM_NR_set_tls syscall. - * - * This could be used as follows: - * - * #define __kernel_get_tls() \ - * ({ register unsigned int __val asm("r0"); \ - * asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \ - * : "=r" (__val) : : "lr","cc" ); \ - * __val; }) - */ - __kuser_get_tls: @ 0xffff0fe0 ldr r0, [pc, #(16 - 8)] @ read TLS, set in kuser_get_tls_init usr_ret lr @@ -1000,19 +862,6 @@ __kuser_get_tls: @ 0xffff0fe0 .word 0 @ 0xffff0ff0 software TLS value, then .endr @ pad up to __kuser_helper_version -/* - * Reference declaration: - * - * extern unsigned int __kernel_helper_version; - * - * Definition and user space usage example: - * - * #define __kernel_helper_version (*(unsigned int *)0xffff0ffc) - * - * User space may read this to determine the curent number of helpers - * available. - */ - __kuser_helper_version: @ 0xffff0ffc .word ((__kuser_helper_end - __kuser_helper_start) >> 5) -- cgit v1.2.3 From b69874e4f530b0103e507f695c010d00cb85a4df Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 21 Jun 2011 18:57:31 +0100 Subject: ARM: pm: arrange for cpu_proc_init() to be called on resume cpu_proc_init() does processor specific initialization, which we do at boot time. We have been omitting to do this on resume, which causes some of this initialization to be skipped. We've also been skipping this on SMP initialization too. Ensure that cpu_proc_init() is always called appropriately by moving it into cpu_init(), and move cpu_init() to a more appropriate point in the boot initialization. Tested-by: Kevin Hilman Acked-by: Jean Pihet Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 99 ++++++++++++++++++++++++----------------------- arch/arm/mm/proc-sa1100.S | 4 +- 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index ed11fb08b05a..edcab02be64c 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -342,54 +342,6 @@ static void __init feat_v6_fixup(void) elf_hwcap &= ~HWCAP_TLS; } -static void __init setup_processor(void) -{ - struct proc_info_list *list; - - /* - * locate processor in the list of supported processor - * types. The linker builds this table for us from the - * entries in arch/arm/mm/proc-*.S - */ - list = lookup_processor_type(read_cpuid_id()); - if (!list) { - printk("CPU configuration botched (ID %08x), unable " - "to continue.\n", read_cpuid_id()); - while (1); - } - - cpu_name = list->cpu_name; - -#ifdef MULTI_CPU - processor = *list->proc; -#endif -#ifdef MULTI_TLB - cpu_tlb = *list->tlb; -#endif -#ifdef MULTI_USER - cpu_user = *list->user; -#endif -#ifdef MULTI_CACHE - cpu_cache = *list->cache; -#endif - - printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", - cpu_name, read_cpuid_id(), read_cpuid_id() & 15, - proc_arch[cpu_architecture()], cr_alignment); - - sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS); - sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); - elf_hwcap = list->elf_hwcap; -#ifndef CONFIG_ARM_THUMB - elf_hwcap &= ~HWCAP_THUMB; -#endif - - feat_v6_fixup(); - - cacheid_init(); - cpu_proc_init(); -} - /* * cpu_init - initialise one CPU. * @@ -405,6 +357,8 @@ void cpu_init(void) BUG(); } + cpu_proc_init(); + /* * Define the placement constraint for the inline asm directive below. * In Thumb-2, msr with an immediate value is not allowed. @@ -441,6 +395,54 @@ void cpu_init(void) : "r14"); } +static void __init setup_processor(void) +{ + struct proc_info_list *list; + + /* + * locate processor in the list of supported processor + * types. The linker builds this table for us from the + * entries in arch/arm/mm/proc-*.S + */ + list = lookup_processor_type(read_cpuid_id()); + if (!list) { + printk("CPU configuration botched (ID %08x), unable " + "to continue.\n", read_cpuid_id()); + while (1); + } + + cpu_name = list->cpu_name; + +#ifdef MULTI_CPU + processor = *list->proc; +#endif +#ifdef MULTI_TLB + cpu_tlb = *list->tlb; +#endif +#ifdef MULTI_USER + cpu_user = *list->user; +#endif +#ifdef MULTI_CACHE + cpu_cache = *list->cache; +#endif + + printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", + cpu_name, read_cpuid_id(), read_cpuid_id() & 15, + proc_arch[cpu_architecture()], cr_alignment); + + sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS); + sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); + elf_hwcap = list->elf_hwcap; +#ifndef CONFIG_ARM_THUMB + elf_hwcap &= ~HWCAP_THUMB; +#endif + + feat_v6_fixup(); + + cacheid_init(); + cpu_init(); +} + void __init dump_machine_table(void) { struct machine_desc *p; @@ -913,7 +915,6 @@ void __init setup_arch(char **cmdline_p) #endif reserve_crashkernel(); - cpu_init(); tcm_init(); #ifdef CONFIG_MULTI_IRQ_HANDLER diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 184a9c997e36..e9c47271732d 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S @@ -34,7 +34,7 @@ */ #define DCACHELINESIZE 32 - __INIT + .section .text /* * cpu_sa1100_proc_init() @@ -45,8 +45,6 @@ ENTRY(cpu_sa1100_proc_init) mcr p15, 0, r0, c9, c0, 5 @ Allow read-buffer operations from userland mov pc, lr - .section .text - /* * cpu_sa1100_proc_fin() * -- cgit v1.2.3 From 3125af241cdb5a2421aad9f710b2744228a79084 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 21 Jun 2011 18:59:33 +0100 Subject: ARM: pm: sa1100: no need to re-enable clock switching This is now taken care of by calling cpu_proc_init() in the resume path, so eliminate this unnecessary call. Tested-by: Kevin Hilman Acked-by: Jean Pihet Signed-off-by: Russell King --- arch/arm/mach-sa1100/sleep.S | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S index 04f2a618d4ef..122ab3c66923 100644 --- a/arch/arm/mach-sa1100/sleep.S +++ b/arch/arm/mach-sa1100/sleep.S @@ -147,5 +147,4 @@ sa1110_sdram_controller_fix: */ .align 5 sa1100_cpu_resume: - mcr p15, 0, r1, c15, c1, 2 @ enable clock switching ldmfd sp!, {r4 - r12, pc} @ return to caller -- cgit v1.2.3 From 6b5f6ab0e1c33beaed828271f13c03ed02ee3c15 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 13:39:44 +0100 Subject: ARM: pm: make MULTI_CPU and !MULTI_CPU resume paths the same Eliminate the differences between MULTI_CPU and non-MULTI_CPU resume paths, making the saved structure identical irrespective of the way the kernel was configured. Acked-by: Frank Hofmann Tested-by: Kevin Hilman Acked-by: Jean Pihet Signed-off-by: Russell King --- arch/arm/kernel/sleep.S | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 6398ead9d1c0..97a6577aa61e 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -40,9 +40,11 @@ ENTRY(cpu_suspend) #else mov r2, sp @ current virtual SP ldr r0, =cpu_suspend_size + ldr ip, =cpu_do_resume sub sp, sp, r0 @ allocate CPU state on stack mov r0, sp @ save pointer - stmfd sp!, {r1, r2, r3} @ save v:p, virt SP, return fn + add ip, ip, r1 @ convert resume fn to phys + stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn ldr r3, =sleep_save_sp add r2, sp, r1 @ convert SP to phys #ifdef CONFIG_SMP @@ -120,20 +122,12 @@ ENTRY(cpu_resume) ldr r0, sleep_save_sp @ stack phys addr #endif setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off -#ifdef MULTI_CPU @ load v:p, stack, return fn, resume fn ARM( ldmia r0!, {r1, sp, lr, pc} ) THUMB( ldmia r0!, {r1, r2, r3, r4} ) THUMB( mov sp, r2 ) THUMB( mov lr, r3 ) THUMB( bx r4 ) -#else - @ load v:p, stack, return fn - ARM( ldmia r0!, {r1, sp, lr} ) -THUMB( ldmia r0!, {r1, r2, lr} ) -THUMB( mov sp, r2 ) - b cpu_do_resume -#endif ENDPROC(cpu_resume) sleep_save_sp: -- cgit v1.2.3 From 2fefbcd58590cf33189c6178098e12b31b994b5f Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 13:45:34 +0100 Subject: ARM: pm: move return address (for cpu_resume) to top of stack Move the return address for cpu_resume to the top of stack so that cpu_resume looks more like a normal function. Acked-by: Frank Hofmann Tested-by: Kevin Hilman Acked-by: Jean Pihet Signed-off-by: Russell King --- arch/arm/kernel/sleep.S | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 97a6577aa61e..f8e92513c1bd 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -15,6 +15,7 @@ * r0-r3,r9,r10,lr corrupted */ ENTRY(cpu_suspend) + stmfd sp!, {r3} mov r9, lr #ifdef MULTI_CPU ldr r10, =processor @@ -24,7 +25,7 @@ ENTRY(cpu_suspend) sub sp, sp, r0 @ allocate CPU state on stack mov r0, sp @ save pointer add ip, ip, r1 @ convert resume fn to phys - stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn + stmfd sp!, {r1, r2, ip} @ save v:p, virt SP, phys resume fn ldr r3, =sleep_save_sp add r2, sp, r1 @ convert SP to phys #ifdef CONFIG_SMP @@ -44,7 +45,7 @@ ENTRY(cpu_suspend) sub sp, sp, r0 @ allocate CPU state on stack mov r0, sp @ save pointer add ip, ip, r1 @ convert resume fn to phys - stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn + stmfd sp!, {r1, r2, ip} @ save v:p, virt SP, phys resume fn ldr r3, =sleep_save_sp add r2, sp, r1 @ convert SP to phys #ifdef CONFIG_SMP @@ -99,7 +100,7 @@ ENDPROC(cpu_resume_turn_mmu_on) cpu_resume_after_mmu: str r5, [r2, r4, lsl #2] @ restore old mapping mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache - mov pc, lr + ldmfd sp!, {pc} ENDPROC(cpu_resume_after_mmu) /* @@ -122,12 +123,11 @@ ENTRY(cpu_resume) ldr r0, sleep_save_sp @ stack phys addr #endif setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off - @ load v:p, stack, return fn, resume fn - ARM( ldmia r0!, {r1, sp, lr, pc} ) -THUMB( ldmia r0!, {r1, r2, r3, r4} ) + @ load v:p, stack, resume fn + ARM( ldmia r0!, {r1, sp, pc} ) +THUMB( ldmia r0!, {r1, r2, r3} ) THUMB( mov sp, r2 ) -THUMB( mov lr, r3 ) -THUMB( bx r4 ) +THUMB( bx r3 ) ENDPROC(cpu_resume) sleep_save_sp: -- cgit v1.2.3 From 3fd431bd0cbc75a506b90b42619de3b04fe813a7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 13:53:06 +0100 Subject: ARM: pm: extract common code from MULTI_CPU/!MULTI_CPU paths Very little code is different between these two paths now, so extract the common code. Acked-by: Frank Hofmann Tested-by: Kevin Hilman Acked-by: Jean Pihet Signed-off-by: Russell King --- arch/arm/kernel/sleep.S | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index f8e92513c1bd..0a778c30859b 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -19,29 +19,13 @@ ENTRY(cpu_suspend) mov r9, lr #ifdef MULTI_CPU ldr r10, =processor - mov r2, sp @ current virtual SP ldr r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function - sub sp, sp, r0 @ allocate CPU state on stack - mov r0, sp @ save pointer - add ip, ip, r1 @ convert resume fn to phys - stmfd sp!, {r1, r2, ip} @ save v:p, virt SP, phys resume fn - ldr r3, =sleep_save_sp - add r2, sp, r1 @ convert SP to phys -#ifdef CONFIG_SMP - ALT_SMP(mrc p15, 0, lr, c0, c0, 5) - ALT_UP(mov lr, #0) - and lr, lr, #15 - str r2, [r3, lr, lsl #2] @ save phys SP #else - str r2, [r3] @ save phys SP -#endif - mov lr, pc - ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state -#else - mov r2, sp @ current virtual SP ldr r0, =cpu_suspend_size ldr ip, =cpu_do_resume +#endif + mov r2, sp @ current virtual SP sub sp, sp, r0 @ allocate CPU state on stack mov r0, sp @ save pointer add ip, ip, r1 @ convert resume fn to phys @@ -56,6 +40,10 @@ ENTRY(cpu_suspend) #else str r2, [r3] @ save phys SP #endif +#ifdef MULTI_CPU + mov lr, pc + ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state +#else bl cpu_do_suspend #endif -- cgit v1.2.3 From 5fa94c812c0001ac7c3d8868e956ec514734a352 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 15:04:14 +0100 Subject: ARM: pm: preserve r4 - r11 across a suspend Make cpu_suspend()..return function preserve r4 to r11 across a suspend cycle. This is in preparation of relieving platform support code from this task. Acked-by: Frank Hofmann Tested-by: Kevin Hilman Acked-by: Jean Pihet Signed-off-by: Russell King --- arch/arm/kernel/sleep.S | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 0a778c30859b..8dbca93417ff 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -12,10 +12,11 @@ * r1 = v:p offset * r3 = virtual return function * Note: sp is decremented to allocate space for CPU state on stack - * r0-r3,r9,r10,lr corrupted + * r0-r3,ip,lr corrupted */ ENTRY(cpu_suspend) stmfd sp!, {r3} + stmfd sp!, {r4 - r11} mov r9, lr #ifdef MULTI_CPU ldr r10, =processor @@ -88,7 +89,7 @@ ENDPROC(cpu_resume_turn_mmu_on) cpu_resume_after_mmu: str r5, [r2, r4, lsl #2] @ restore old mapping mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache - ldmfd sp!, {pc} + ldmfd sp!, {r4 - r11, pc} ENDPROC(cpu_resume_after_mmu) /* -- cgit v1.2.3 From 8111eaa6d424ab3ba8a4d7a3148d4681ae5c6ae3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 15:25:11 +0100 Subject: ARM: pm: reallocate registers to avoid r2, r3 Avoid using r2 and r3 in the suspend code, allowing these to be passed further into the function as arguments. Acked-by: Frank Hofmann Tested-by: Kevin Hilman Acked-by: Jean Pihet Signed-off-by: Russell King --- arch/arm/kernel/sleep.S | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 8dbca93417ff..358be13499da 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -20,26 +20,26 @@ ENTRY(cpu_suspend) mov r9, lr #ifdef MULTI_CPU ldr r10, =processor - ldr r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state + ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function #else - ldr r0, =cpu_suspend_size + ldr r5, =cpu_suspend_size ldr ip, =cpu_do_resume #endif - mov r2, sp @ current virtual SP - sub sp, sp, r0 @ allocate CPU state on stack + mov r6, sp @ current virtual SP + sub sp, sp, r5 @ allocate CPU state on stack mov r0, sp @ save pointer add ip, ip, r1 @ convert resume fn to phys - stmfd sp!, {r1, r2, ip} @ save v:p, virt SP, phys resume fn - ldr r3, =sleep_save_sp - add r2, sp, r1 @ convert SP to phys + stmfd sp!, {r1, r6, ip} @ save v:p, virt SP, phys resume fn + ldr r5, =sleep_save_sp + add r6, sp, r1 @ convert SP to phys #ifdef CONFIG_SMP ALT_SMP(mrc p15, 0, lr, c0, c0, 5) ALT_UP(mov lr, #0) and lr, lr, #15 - str r2, [r3, lr, lsl #2] @ save phys SP + str r6, [r5, lr, lsl #2] @ save phys SP #else - str r2, [r3] @ save phys SP + str r6, [r5] @ save phys SP #endif #ifdef MULTI_CPU mov lr, pc -- cgit v1.2.3 From 3799bbe57843d279008c9ec3406838966cad5f15 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 15:28:40 +0100 Subject: ARM: pm: rejig suspend follow-on function calling convention Save the suspend function pointer onto the stack for use when returning. Allocate r2 to pass an argument to the suspend function. Acked-by: Frank Hofmann Tested-by: Kevin Hilman Acked-by: Jean Pihet Signed-off-by: Russell King --- arch/arm/kernel/sleep.S | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 358be13499da..b924bcc32dcd 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -10,6 +10,7 @@ /* * Save CPU state for a suspend * r1 = v:p offset + * r2 = suspend function arg0 * r3 = virtual return function * Note: sp is decremented to allocate space for CPU state on stack * r0-r3,ip,lr corrupted @@ -17,7 +18,6 @@ ENTRY(cpu_suspend) stmfd sp!, {r3} stmfd sp!, {r4 - r11} - mov r9, lr #ifdef MULTI_CPU ldr r10, =processor ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state @@ -33,6 +33,7 @@ ENTRY(cpu_suspend) stmfd sp!, {r1, r6, ip} @ save v:p, virt SP, phys resume fn ldr r5, =sleep_save_sp add r6, sp, r1 @ convert SP to phys + stmfd sp!, {r2, lr} @ save suspend func arg and pointer #ifdef CONFIG_SMP ALT_SMP(mrc p15, 0, lr, c0, c0, 5) ALT_UP(mov lr, #0) @@ -51,12 +52,12 @@ ENTRY(cpu_suspend) @ flush data cache #ifdef MULTI_CACHE ldr r10, =cpu_cache - mov lr, r9 + mov lr, pc ldr pc, [r10, #CACHE_FLUSH_KERN_ALL] #else - mov lr, r9 - b __cpuc_flush_kern_all + bl __cpuc_flush_kern_all #endif + ldmfd sp!, {r0, pc} @ call suspend fn ENDPROC(cpu_suspend) .ltorg -- cgit v1.2.3 From dbc125168fd7dda4ffb24a29548746c7bd3b3d87 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 15:52:47 +0100 Subject: ARM: pm: move sa1100 to use proper suspend func arg0 In the previous commit, we introduced an official way to supply an argument to the suspend function. Convert the sa1100 suspend code to use this method. Signed-off-by: Russell King --- arch/arm/mach-pxa/sleep.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index 6f5368899d84..613ddfa2c295 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S @@ -59,7 +59,7 @@ ENTRY(pxa27x_cpu_suspend) mra r2, r3, acc0 #endif stmfd sp!, {r2 - r12, lr} @ save registers on stack - mov r4, r0 @ save sleep mode + mov r2, r0 @ save sleep mode ldr r3, =pxa_cpu_resume @ resume function bl cpu_suspend @@ -67,7 +67,7 @@ ENTRY(pxa27x_cpu_suspend) @ (also workaround for sighting 28071) @ prepare value for sleep mode - mov r1, r4 @ sleep mode + mov r1, r0 @ sleep mode @ prepare pointer to physical address 0 (virtual mapping in generic.c) mov r2, #UNCACHED_PHYS_0 @@ -109,11 +109,11 @@ ENTRY(pxa27x_cpu_suspend) ENTRY(pxa25x_cpu_suspend) stmfd sp!, {r2 - r12, lr} @ save registers on stack - mov r4, r0 @ save sleep mode + mov r2, r0 @ save sleep mode ldr r3, =pxa_cpu_resume @ resume function bl cpu_suspend @ prepare value for sleep mode - mov r1, r4 @ sleep mode + mov r1, r0 @ sleep mode @ prepare pointer to physical address 0 (virtual mapping in generic.c) mov r2, #UNCACHED_PHYS_0 -- cgit v1.2.3 From e8856a8797e76e6883ae81f8f9ecbb231cc535df Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 15:58:34 +0100 Subject: ARM: pm: convert cpu_suspend() to a normal function cpu_suspend() has a weird calling method which makes it only possible to call from assembly code: it returns with a modified stack pointer to finish the suspend, but on resume, it 'returns' via a provided pointer. We can make cpu_suspend() appear to be a normal function merely by swapping the resume pointer argument and the link register. Do so, and update all callers to take account of this more traditional behaviour. Acked-by: Frank Hofmann Tested-by: Kevin Hilman Acked-by: Jean Pihet Signed-off-by: Russell King --- arch/arm/include/asm/system.h | 2 ++ arch/arm/kernel/sleep.S | 10 ++++------ arch/arm/mach-exynos4/sleep.S | 7 +++---- arch/arm/mach-pxa/sleep.S | 13 ++++++++++--- arch/arm/mach-s3c64xx/sleep.S | 9 +++------ arch/arm/mach-s5pv210/sleep.S | 7 +++---- arch/arm/mach-sa1100/sleep.S | 13 +++---------- arch/arm/plat-s3c24xx/sleep.S | 10 +++------- 8 files changed, 31 insertions(+), 40 deletions(-) diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 832888d0c20c..50be6055df89 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -106,6 +106,8 @@ extern void __show_regs(struct pt_regs *); extern int cpu_architecture(void); extern void cpu_init(void); +extern void cpu_suspend(int, long, unsigned long, void (*)(unsigned long)); +extern void cpu_resume(void); void arm_machine_restart(char mode, const char *cmd); extern void (*arm_pm_restart)(char str, const char *cmd); diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index b924bcc32dcd..e0626779fe92 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -11,13 +11,11 @@ * Save CPU state for a suspend * r1 = v:p offset * r2 = suspend function arg0 - * r3 = virtual return function - * Note: sp is decremented to allocate space for CPU state on stack - * r0-r3,ip,lr corrupted + * r3 = suspend function + * Note: does not return until system resumes */ ENTRY(cpu_suspend) - stmfd sp!, {r3} - stmfd sp!, {r4 - r11} + stmfd sp!, {r4 - r11, lr} #ifdef MULTI_CPU ldr r10, =processor ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state @@ -33,7 +31,7 @@ ENTRY(cpu_suspend) stmfd sp!, {r1, r6, ip} @ save v:p, virt SP, phys resume fn ldr r5, =sleep_save_sp add r6, sp, r1 @ convert SP to phys - stmfd sp!, {r2, lr} @ save suspend func arg and pointer + stmfd sp!, {r2, r3} @ save suspend func arg and pointer #ifdef CONFIG_SMP ALT_SMP(mrc p15, 0, lr, c0, c0, 5) ALT_UP(mov lr, #0) diff --git a/arch/arm/mach-exynos4/sleep.S b/arch/arm/mach-exynos4/sleep.S index 6b62425417a6..d9a2287b4641 100644 --- a/arch/arm/mach-exynos4/sleep.S +++ b/arch/arm/mach-exynos4/sleep.S @@ -42,16 +42,15 @@ ENTRY(s3c_cpu_save) stmfd sp!, { r3 - r12, lr } - ldr r3, =resume_with_mmu + adr r3, BSYM(exynos4_finish_suspend) bl cpu_suspend + ldmfd sp!, { r3 - r12, pc } +exynos4_finish_suspend: ldr r0, =pm_cpu_sleep ldr r0, [ r0 ] mov pc, r0 -resume_with_mmu: - ldmfd sp!, { r3 - r12, pc } - .ltorg /* diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index 613ddfa2c295..3a67887e6dbd 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S @@ -35,9 +35,11 @@ ENTRY(pxa3xx_cpu_suspend) #endif stmfd sp!, {r2 - r12, lr} @ save registers on stack mov r1, r0 - ldr r3, =pxa_cpu_resume @ resume function + adr r3, BSYM(pxa3xx_finish_suspend) bl cpu_suspend + b pxa_cpu_resume +pxa3xx_finish_suspend: mov r0, #0x06 @ S2D3C4 mode mcr p14, 0, r0, c7, c0, 0 @ enter sleep @@ -60,9 +62,11 @@ ENTRY(pxa27x_cpu_suspend) #endif stmfd sp!, {r2 - r12, lr} @ save registers on stack mov r2, r0 @ save sleep mode - ldr r3, =pxa_cpu_resume @ resume function + adr r3, BSYM(pxa27x_finish_suspend) bl cpu_suspend + b pxa_cpu_resume +pxa27x_finish_suspend: @ Put the processor to sleep @ (also workaround for sighting 28071) @@ -110,8 +114,11 @@ ENTRY(pxa27x_cpu_suspend) ENTRY(pxa25x_cpu_suspend) stmfd sp!, {r2 - r12, lr} @ save registers on stack mov r2, r0 @ save sleep mode - ldr r3, =pxa_cpu_resume @ resume function + adr r3, BSYM(pxa25x_finish_suspend) bl cpu_suspend + b pxa_cpu_resume + +pxa25x_finish_suspend: @ prepare value for sleep mode mov r1, r0 @ sleep mode diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S index 1f87732b2320..dc4f58202101 100644 --- a/arch/arm/mach-s3c64xx/sleep.S +++ b/arch/arm/mach-s3c64xx/sleep.S @@ -36,18 +36,15 @@ ENTRY(s3c_cpu_save) stmfd sp!, { r4 - r12, lr } - ldr r3, =resume_with_mmu + adr r3, BSYM(s3c64xx_finish_suspend) bl cpu_suspend + ldmfd sp!, { r4 - r12, pc } +s3c64xx_finish_suspend: @@ call final suspend code ldr r0, =pm_cpu_sleep ldr pc, [r0] - @@ return to the caller, after the MMU is turned on. - @@ restore the last bits of the stack and return. -resume_with_mmu: - ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save - /* Sleep magic, the word before the resume entry point so that the * bootloader can check for a resumeable image. */ diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S index a3d649466fb1..1182fc848a79 100644 --- a/arch/arm/mach-s5pv210/sleep.S +++ b/arch/arm/mach-s5pv210/sleep.S @@ -41,16 +41,15 @@ ENTRY(s3c_cpu_save) stmfd sp!, { r3 - r12, lr } - ldr r3, =resume_with_mmu + adr r3, BSYM(s5pv210_finish_suspend) bl cpu_suspend + ldmfd sp!, { r3 - r12, pc } +s5pv210_finish_suspend: ldr r0, =pm_cpu_sleep ldr r0, [ r0 ] mov pc, r0 -resume_with_mmu: - ldmfd sp!, { r3 - r12, pc } - .ltorg /* sleep magic, to allow the bootloader to check for an valid diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S index 122ab3c66923..f3fe39773f8b 100644 --- a/arch/arm/mach-sa1100/sleep.S +++ b/arch/arm/mach-sa1100/sleep.S @@ -31,9 +31,11 @@ ENTRY(sa1100_cpu_suspend) stmfd sp!, {r4 - r12, lr} @ save registers on stack mov r1, r0 - ldr r3, =sa1100_cpu_resume @ return function + adr r3, BSYM(sa1100_finish_suspend) bl cpu_suspend + ldmfd sp!, {r4 - r12, pc} @ return to caller +sa1100_finish_suspend: @ disable clock switching mcr p15, 0, r1, c15, c2, 2 @@ -139,12 +141,3 @@ sa1110_sdram_controller_fix: str r13, [r12] 20: b 20b @ loop waiting for sleep - -/* - * cpu_sa1100_resume() - * - * entry point from bootloader into kernel during resume - */ - .align 5 -sa1100_cpu_resume: - ldmfd sp!, {r4 - r12, pc} @ return to caller diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S index fd7032f84ae7..f822e6282dd4 100644 --- a/arch/arm/plat-s3c24xx/sleep.S +++ b/arch/arm/plat-s3c24xx/sleep.S @@ -49,21 +49,17 @@ ENTRY(s3c_cpu_save) stmfd sp!, { r4 - r12, lr } - ldr r3, =resume_with_mmu + adr r3, BSYM(s3c24xx_finish_suspend) bl cpu_suspend + ldmfd sp!, { r4 - r12, pc } +s3c24xx_finish_suspend: @@ jump to final code to send system to sleep ldr r0, =pm_cpu_sleep @@ldr pc, [ r0 ] ldr r0, [ r0 ] mov pc, r0 - @@ return to the caller, after having the MMU - @@ turned on, this restores the last bits from the - @@ stack -resume_with_mmu: - ldmfd sp!, { r4 - r12, pc } - .ltorg /* sleep magic, to allow the bootloader to check for an valid -- cgit v1.2.3 From 14cd8fd574bce1cfbe510ccb1f73c7c1024d770f Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 21 Jun 2011 16:32:58 +0100 Subject: ARM: pm: move cpu_init() call into core code As we have core code dealing with CPU suspend/resume, we can re-initialize the CPUs exception banked registers via that code rather than having platforms deal with that level of detail. So, move the call to cpu_init() out of platform code into core code. Tested-by: Kevin Hilman Acked-by: Jean Pihet Signed-off-by: Russell King --- arch/arm/kernel/sleep.S | 1 + arch/arm/mach-pxa/pm.c | 1 - arch/arm/mach-sa1100/pm.c | 2 -- arch/arm/plat-samsung/pm.c | 4 ---- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index e0626779fe92..53922748d101 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -88,6 +88,7 @@ ENDPROC(cpu_resume_turn_mmu_on) cpu_resume_after_mmu: str r5, [r2, r4, lsl #2] @ restore old mapping mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache + bl cpu_init @ restore the und/abt/irq banked regs ldmfd sp!, {r4 - r11, pc} ENDPROC(cpu_resume_after_mmu) diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 51e1583265b2..37178a8559b1 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -42,7 +42,6 @@ int pxa_pm_enter(suspend_state_t state) /* *** go zzz *** */ pxa_cpu_pm_fns->enter(state); - cpu_init(); if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->restore) { /* after sleeping, validate the checksum */ diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index c4661aab22fb..d35885ca97a1 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c @@ -77,8 +77,6 @@ static int sa11x0_pm_enter(suspend_state_t state) /* go zzz */ sa1100_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET); - cpu_init(); - /* * Ensure not to come back here if it wasn't intended */ diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 5c0a440d6e16..3828191416b5 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c @@ -300,10 +300,6 @@ static int s3c_pm_enter(suspend_state_t state) s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET); - /* restore the cpu state using the kernel's cpu init code. */ - - cpu_init(); - /* restore the system state */ s3c_pm_restore_core(); -- cgit v1.2.3 From 34c79de6b2ea5bc5734d970851fb966b49d55a17 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 21 Jun 2011 16:26:29 +0100 Subject: ARM: pm: sa1100: move cpu_suspend into C code We don't need a veneer for cpu_suspend, it can be called directly from C code now. Move it into sa11x0_pm_enter() along with the re-enabling of clock switching. Signed-off-by: Russell King --- arch/arm/mach-sa1100/pm.c | 4 ++-- arch/arm/mach-sa1100/sleep.S | 11 ++--------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index d35885ca97a1..259ed3bcc3fe 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c @@ -32,7 +32,7 @@ #include #include -extern void sa1100_cpu_suspend(long); +extern void sa1100_finish_suspend(unsigned long); #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] @@ -75,7 +75,7 @@ static int sa11x0_pm_enter(suspend_state_t state) PSPR = virt_to_phys(cpu_resume); /* go zzz */ - sa1100_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET); + cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, 0, sa1100_finish_suspend); /* * Ensure not to come back here if it wasn't intended diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S index f3fe39773f8b..e8223315b442 100644 --- a/arch/arm/mach-sa1100/sleep.S +++ b/arch/arm/mach-sa1100/sleep.S @@ -22,20 +22,13 @@ .text /* - * sa1100_cpu_suspend() + * sa1100_finish_suspend() * * Causes sa11x0 to enter sleep state * */ -ENTRY(sa1100_cpu_suspend) - stmfd sp!, {r4 - r12, lr} @ save registers on stack - mov r1, r0 - adr r3, BSYM(sa1100_finish_suspend) - bl cpu_suspend - ldmfd sp!, {r4 - r12, pc} @ return to caller - -sa1100_finish_suspend: +ENTRY(sa1100_finish_suspend) @ disable clock switching mcr p15, 0, r1, c15, c2, 2 -- cgit v1.2.3 From c4ac82c07dd3e4fb5d65a52ffa94e302f80b609d Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 16:03:19 +0100 Subject: ARM: pm: plat-s3c24xx: cleanup s3c_cpu_save s3c_cpu_save does not need to save any registers with the new cpu_suspend calling convention. Remove these redundant instructions. Tested-by: Kukjin Kim Signed-off-by: Russell King --- arch/arm/plat-s3c24xx/sleep.S | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S index f822e6282dd4..6ada459498a8 100644 --- a/arch/arm/plat-s3c24xx/sleep.S +++ b/arch/arm/plat-s3c24xx/sleep.S @@ -48,10 +48,8 @@ */ ENTRY(s3c_cpu_save) - stmfd sp!, { r4 - r12, lr } adr r3, BSYM(s3c24xx_finish_suspend) - bl cpu_suspend - ldmfd sp!, { r4 - r12, pc } + b cpu_suspend s3c24xx_finish_suspend: @@ jump to final code to send system to sleep -- cgit v1.2.3 From 3d32ead3f16f054fa7f4a85a34eb12c36fd76269 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 16:10:16 +0100 Subject: ARM: pm: mach-s5pv210: cleanup s3c_cpu_save s3c_cpu_save does not need to save any registers with the new cpu_suspend calling convention. Remove these redundant instructions. Signed-off-by: Russell King --- arch/arm/mach-s5pv210/sleep.S | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S index 1182fc848a79..28dfeff342b8 100644 --- a/arch/arm/mach-s5pv210/sleep.S +++ b/arch/arm/mach-s5pv210/sleep.S @@ -39,11 +39,8 @@ */ ENTRY(s3c_cpu_save) - - stmfd sp!, { r3 - r12, lr } adr r3, BSYM(s5pv210_finish_suspend) - bl cpu_suspend - ldmfd sp!, { r3 - r12, pc } + b cpu_suspend s5pv210_finish_suspend: ldr r0, =pm_cpu_sleep -- cgit v1.2.3 From 769783a9300d47236766345cc98ce963122c2e4f Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 16:12:27 +0100 Subject: ARM: pm: mach-exynos4: cleanup s3c_cpu_save s3c_cpu_save does not need to save any registers with the new cpu_suspend calling convention. Remove these redundant instructions. Signed-off-by: Russell King --- arch/arm/mach-exynos4/sleep.S | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/arm/mach-exynos4/sleep.S b/arch/arm/mach-exynos4/sleep.S index d9a2287b4641..b56a4914985c 100644 --- a/arch/arm/mach-exynos4/sleep.S +++ b/arch/arm/mach-exynos4/sleep.S @@ -40,11 +40,8 @@ */ ENTRY(s3c_cpu_save) - - stmfd sp!, { r3 - r12, lr } adr r3, BSYM(exynos4_finish_suspend) - bl cpu_suspend - ldmfd sp!, { r3 - r12, pc } + b cpu_suspend exynos4_finish_suspend: ldr r0, =pm_cpu_sleep -- cgit v1.2.3 From 4d01446fea61a32b6755ae1e11314ffca744dcaa Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 13 Jun 2011 16:33:30 +0100 Subject: ARM: pm: mach-s3c64xx: cleanup s3c_cpu_save s3c_cpu_save does not need to save any registers with the new cpu_suspend calling convention. Remove these redundant instructions. Acked-by: Frank Hofmann Signed-off-by: Russell King --- arch/arm/mach-s3c64xx/sleep.S | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S index dc4f58202101..2fd343332838 100644 --- a/arch/arm/mach-s3c64xx/sleep.S +++ b/arch/arm/mach-s3c64xx/sleep.S @@ -35,10 +35,8 @@ */ ENTRY(s3c_cpu_save) - stmfd sp!, { r4 - r12, lr } adr r3, BSYM(s3c64xx_finish_suspend) - bl cpu_suspend - ldmfd sp!, { r4 - r12, pc } + b cpu_suspend s3c64xx_finish_suspend: @@ call final suspend code -- cgit v1.2.3 From e7089da9567fa8da37e35e1f81a5e3579d0d582d Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 21 Jun 2011 19:29:26 +0100 Subject: ARM: pm: samsung: move cpu_suspend into C code Move the call to cpu_suspend into C code, and noticing that all the s3c_cpu_save implementations are now identical, we can move this into the common samsung code. Signed-off-by: Russell King --- arch/arm/mach-exynos4/pm.c | 2 +- arch/arm/mach-exynos4/sleep.S | 18 ------------------ arch/arm/mach-s3c2412/pm.c | 2 +- arch/arm/mach-s3c2416/pm.c | 2 +- arch/arm/mach-s3c64xx/pm.c | 2 +- arch/arm/mach-s3c64xx/sleep.S | 18 ------------------ arch/arm/mach-s5pv210/pm.c | 2 +- arch/arm/mach-s5pv210/sleep.S | 17 ----------------- arch/arm/plat-s3c24xx/sleep.S | 19 ------------------- arch/arm/plat-samsung/include/plat/pm.h | 5 ++--- arch/arm/plat-samsung/pm.c | 6 +++--- 11 files changed, 10 insertions(+), 83 deletions(-) diff --git a/arch/arm/mach-exynos4/pm.c b/arch/arm/mach-exynos4/pm.c index 8755ca8dd48d..5c01c6076645 100644 --- a/arch/arm/mach-exynos4/pm.c +++ b/arch/arm/mach-exynos4/pm.c @@ -280,7 +280,7 @@ static struct sleep_save exynos4_l2cc_save[] = { SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL), }; -void exynos4_cpu_suspend(void) +void exynos4_cpu_suspend(unsigned long arg) { unsigned long tmp; unsigned long mask = 0xFFFFFFFF; diff --git a/arch/arm/mach-exynos4/sleep.S b/arch/arm/mach-exynos4/sleep.S index b56a4914985c..0984078f1eba 100644 --- a/arch/arm/mach-exynos4/sleep.S +++ b/arch/arm/mach-exynos4/sleep.S @@ -32,24 +32,6 @@ .text - /* - * s3c_cpu_save - * - * entry: - * r1 = v:p offset - */ - -ENTRY(s3c_cpu_save) - adr r3, BSYM(exynos4_finish_suspend) - b cpu_suspend - -exynos4_finish_suspend: - ldr r0, =pm_cpu_sleep - ldr r0, [ r0 ] - mov pc, r0 - - .ltorg - /* * sleep magic, to allow the bootloader to check for an valid * image to resume to. Must be the first word before the diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c index 752b13a7b3db..fecd85489e51 100644 --- a/arch/arm/mach-s3c2412/pm.c +++ b/arch/arm/mach-s3c2412/pm.c @@ -37,7 +37,7 @@ extern void s3c2412_sleep_enter(void); -static void s3c2412_cpu_suspend(void) +static void s3c2412_cpu_suspend(unsigned long arg) { unsigned long tmp; diff --git a/arch/arm/mach-s3c2416/pm.c b/arch/arm/mach-s3c2416/pm.c index 41db2b21e213..268fda744201 100644 --- a/arch/arm/mach-s3c2416/pm.c +++ b/arch/arm/mach-s3c2416/pm.c @@ -24,7 +24,7 @@ extern void s3c2412_sleep_enter(void); -static void s3c2416_cpu_suspend(void) +static void s3c2416_cpu_suspend(unsigned long arg) { flush_cache_all(); diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c index bc1c470b7de6..7cc1879af722 100644 --- a/arch/arm/mach-s3c64xx/pm.c +++ b/arch/arm/mach-s3c64xx/pm.c @@ -112,7 +112,7 @@ void s3c_pm_save_core(void) * this. */ -static void s3c64xx_cpu_suspend(void) +static void s3c64xx_cpu_suspend(unsigned long arg) { unsigned long tmp; diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S index 2fd343332838..34313f9c8792 100644 --- a/arch/arm/mach-s3c64xx/sleep.S +++ b/arch/arm/mach-s3c64xx/sleep.S @@ -25,24 +25,6 @@ .text - /* s3c_cpu_save - * - * Save enough processor state to allow the restart of the pm.c - * code after resume. - * - * entry: - * r1 = v:p offset - */ - -ENTRY(s3c_cpu_save) - adr r3, BSYM(s3c64xx_finish_suspend) - b cpu_suspend - -s3c64xx_finish_suspend: - @@ call final suspend code - ldr r0, =pm_cpu_sleep - ldr pc, [r0] - /* Sleep magic, the word before the resume entry point so that the * bootloader can check for a resumeable image. */ diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c index 24febae3d4c0..309e388a8a83 100644 --- a/arch/arm/mach-s5pv210/pm.c +++ b/arch/arm/mach-s5pv210/pm.c @@ -88,7 +88,7 @@ static struct sleep_save s5pv210_core_save[] = { SAVE_ITEM(S3C2410_TCNTO(0)), }; -void s5pv210_cpu_suspend(void) +void s5pv210_cpu_suspend(unsigned long arg) { unsigned long tmp; diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S index 28dfeff342b8..e3452ccd4b08 100644 --- a/arch/arm/mach-s5pv210/sleep.S +++ b/arch/arm/mach-s5pv210/sleep.S @@ -32,23 +32,6 @@ .text - /* s3c_cpu_save - * - * entry: - * r1 = v:p offset - */ - -ENTRY(s3c_cpu_save) - adr r3, BSYM(s5pv210_finish_suspend) - b cpu_suspend - -s5pv210_finish_suspend: - ldr r0, =pm_cpu_sleep - ldr r0, [ r0 ] - mov pc, r0 - - .ltorg - /* sleep magic, to allow the bootloader to check for an valid * image to resume to. Must be the first word before the * s3c_cpu_resume entry. diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S index 6ada459498a8..c56612569b40 100644 --- a/arch/arm/plat-s3c24xx/sleep.S +++ b/arch/arm/plat-s3c24xx/sleep.S @@ -41,25 +41,6 @@ .text - /* s3c_cpu_save - * - * entry: - * r1 = v:p offset - */ - -ENTRY(s3c_cpu_save) - adr r3, BSYM(s3c24xx_finish_suspend) - b cpu_suspend - -s3c24xx_finish_suspend: - @@ jump to final code to send system to sleep - ldr r0, =pm_cpu_sleep - @@ldr pc, [ r0 ] - ldr r0, [ r0 ] - mov pc, r0 - - .ltorg - /* sleep magic, to allow the bootloader to check for an valid * image to resume to. Must be the first word before the * s3c_cpu_resume entry. diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h index 7fb6f6be8c81..0a5b7faca836 100644 --- a/arch/arm/plat-samsung/include/plat/pm.h +++ b/arch/arm/plat-samsung/include/plat/pm.h @@ -42,7 +42,7 @@ extern unsigned long s3c_irqwake_eintallow; /* per-cpu sleep functions */ extern void (*pm_cpu_prep)(void); -extern void (*pm_cpu_sleep)(void); +extern void (*pm_cpu_sleep)(unsigned long); /* Flags for PM Control */ @@ -52,10 +52,9 @@ extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */ /* from sleep.S */ -extern int s3c_cpu_save(unsigned long *saveblk, long); extern void s3c_cpu_resume(void); -extern void s3c2410_cpu_suspend(void); +extern void s3c2410_cpu_suspend(unsigned long); /* sleep save info */ diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 3828191416b5..3a6d0768ba0c 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c @@ -231,7 +231,7 @@ static void __maybe_unused s3c_pm_show_resume_irqs(int start, void (*pm_cpu_prep)(void); -void (*pm_cpu_sleep)(void); +void (*pm_cpu_sleep)(unsigned long); #define any_allowed(mask, allow) (((mask) & (allow)) != (allow)) @@ -294,11 +294,11 @@ static int s3c_pm_enter(suspend_state_t state) s3c_pm_arch_stop_clocks(); - /* s3c_cpu_save will also act as our return point from when + /* this will also act as our return point from when * we resume as it saves its own register state and restores it * during the resume. */ - s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET); + cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, 0, pm_cpu_sleep); /* restore the system state */ -- cgit v1.2.3 From 372c0ac8aca7655b6a8920b10bf9563402ac19d8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 21 Jun 2011 19:34:34 +0100 Subject: ARM: pm: samsung: no need to call flush_cache_all() The core suspend code calls flush_cache_all() immediately prior to calling the suspend finisher function, so remove these needless calls from the finisher functions. Signed-off-by: Russell King --- arch/arm/mach-s3c2412/pm.c | 2 -- arch/arm/mach-s3c2416/pm.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c index fecd85489e51..9a1fb898db53 100644 --- a/arch/arm/mach-s3c2412/pm.c +++ b/arch/arm/mach-s3c2412/pm.c @@ -41,8 +41,6 @@ static void s3c2412_cpu_suspend(unsigned long arg) { unsigned long tmp; - flush_cache_all(); - /* set our standby method to sleep */ tmp = __raw_readl(S3C2412_PWRCFG); diff --git a/arch/arm/mach-s3c2416/pm.c b/arch/arm/mach-s3c2416/pm.c index 268fda744201..9e67a2a07a86 100644 --- a/arch/arm/mach-s3c2416/pm.c +++ b/arch/arm/mach-s3c2416/pm.c @@ -26,8 +26,6 @@ extern void s3c2412_sleep_enter(void); static void s3c2416_cpu_suspend(unsigned long arg) { - flush_cache_all(); - /* enable wakeup sources regardless of battery state */ __raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG); -- cgit v1.2.3 From a9503d2185bbc28e498c435a07f24986c48b5cbe Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 21 Jun 2011 16:29:30 +0100 Subject: ARM: pm: pxa: move cpu_suspend into C code We don't need a veneer for cpu_suspend, it can be called directly from C code now. Move it into the PXA CPU suspend functions, along with the accumulator register saving/restoring. Signed-off-by: Russell King --- arch/arm/mach-pxa/include/mach/pm.h | 4 +-- arch/arm/mach-pxa/pxa25x.c | 3 +- arch/arm/mach-pxa/pxa27x.c | 11 ++++++- arch/arm/mach-pxa/pxa3xx.c | 13 +++++++-- arch/arm/mach-pxa/sleep.S | 58 ++++--------------------------------- arch/arm/mach-pxa/zeus.c | 3 +- 6 files changed, 33 insertions(+), 59 deletions(-) diff --git a/arch/arm/mach-pxa/include/mach/pm.h b/arch/arm/mach-pxa/include/mach/pm.h index f15afe012995..a566720527cf 100644 --- a/arch/arm/mach-pxa/include/mach/pm.h +++ b/arch/arm/mach-pxa/include/mach/pm.h @@ -22,8 +22,8 @@ struct pxa_cpu_pm_fns { extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; /* sleep.S */ -extern void pxa25x_cpu_suspend(unsigned int, long); -extern void pxa27x_cpu_suspend(unsigned int, long); +extern void pxa25x_finish_suspend(unsigned long); +extern void pxa27x_finish_suspend(unsigned long); extern int pxa_pm_enter(suspend_state_t state); extern int pxa_pm_prepare(void); diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index fed363cec9c6..fd7725cb5c01 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -244,7 +244,8 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state) switch (state) { case PM_SUSPEND_MEM: - pxa25x_cpu_suspend(PWRMODE_SLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET); + cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, PWRMODE_SLEEP, + pxa25x_finish_suspend); break; } } diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 2fecbec58d88..824379d43758 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -284,6 +284,11 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save) void pxa27x_cpu_pm_enter(suspend_state_t state) { extern void pxa_cpu_standby(void); +#ifndef CONFIG_IWMMXT + u64 acc0; + + asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); +#endif /* ensure voltage-change sequencer not initiated, which hangs */ PCFR &= ~PCFR_FVC; @@ -299,7 +304,11 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) pxa_cpu_standby(); break; case PM_SUSPEND_MEM: - pxa27x_cpu_suspend(pwrmode, PLAT_PHYS_OFFSET - PAGE_OFFSET); + cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, pwrmode, + pxa27x_finish_suspend); +#ifndef CONFIG_IWMMXT + asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); +#endif break; } } diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 8521d7d6f1da..220fd8c15dab 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -141,8 +141,13 @@ static void pxa3xx_cpu_pm_suspend(void) { volatile unsigned long *p = (volatile void *)0xc0000000; unsigned long saved_data = *p; +#ifndef CONFIG_IWMMXT + u64 acc0; - extern void pxa3xx_cpu_suspend(long); + asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); +#endif + + extern void pxa3xx_finish_suspend(unsigned long); /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */ CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM); @@ -162,11 +167,15 @@ static void pxa3xx_cpu_pm_suspend(void) /* overwrite with the resume address */ *p = virt_to_phys(cpu_resume); - pxa3xx_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET); + cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, 0, pxa3xx_finish_suspend); *p = saved_data; AD3ER = 0; + +#ifndef CONFIG_IWMMXT + asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); +#endif } static void pxa3xx_cpu_pm_enter(suspend_state_t state) diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index 3a67887e6dbd..1e544be9905d 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S @@ -24,22 +24,9 @@ #ifdef CONFIG_PXA3xx /* - * pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4) - * - * r0 = v:p offset + * pxa3xx_finish_suspend() - forces CPU into sleep state (S2D3C4) */ -ENTRY(pxa3xx_cpu_suspend) - -#ifndef CONFIG_IWMMXT - mra r2, r3, acc0 -#endif - stmfd sp!, {r2 - r12, lr} @ save registers on stack - mov r1, r0 - adr r3, BSYM(pxa3xx_finish_suspend) - bl cpu_suspend - b pxa_cpu_resume - -pxa3xx_finish_suspend: +ENTRY(pxa3xx_finish_suspend) mov r0, #0x06 @ S2D3C4 mode mcr p14, 0, r0, c7, c0, 0 @ enter sleep @@ -48,25 +35,13 @@ pxa3xx_finish_suspend: #ifdef CONFIG_PXA27x /* - * pxa27x_cpu_suspend() + * pxa27x_finish_suspend() * * Forces CPU into sleep state. * * r0 = value for PWRMODE M field for desired sleep state - * r1 = v:p offset */ -ENTRY(pxa27x_cpu_suspend) - -#ifndef CONFIG_IWMMXT - mra r2, r3, acc0 -#endif - stmfd sp!, {r2 - r12, lr} @ save registers on stack - mov r2, r0 @ save sleep mode - adr r3, BSYM(pxa27x_finish_suspend) - bl cpu_suspend - b pxa_cpu_resume - -pxa27x_finish_suspend: +ENTRY(pxa27x_finish_suspend) @ Put the processor to sleep @ (also workaround for sighting 28071) @@ -103,22 +78,14 @@ pxa27x_finish_suspend: #ifdef CONFIG_PXA25x /* - * pxa25x_cpu_suspend() + * pxa25x_finish_suspend() * * Forces CPU into sleep state. * * r0 = value for PWRMODE M field for desired sleep state - * r1 = v:p offset */ -ENTRY(pxa25x_cpu_suspend) - stmfd sp!, {r2 - r12, lr} @ save registers on stack - mov r2, r0 @ save sleep mode - adr r3, BSYM(pxa25x_finish_suspend) - bl cpu_suspend - b pxa_cpu_resume - -pxa25x_finish_suspend: +ENTRY(pxa25x_finish_suspend) @ prepare value for sleep mode mov r1, r0 @ sleep mode @@ -202,16 +169,3 @@ pxa_cpu_do_suspend: mcr p14, 0, r1, c7, c0, 0 @ PWRMODE 20: b 20b @ loop waiting for sleep - -/* - * pxa_cpu_resume() - * - * entry point from bootloader into kernel during resume - */ - .align 5 -pxa_cpu_resume: - ldmfd sp!, {r2, r3} -#ifndef CONFIG_IWMMXT - mar acc0, r2, r3 -#endif - ldmfd sp!, {r4 - r12, pc} @ return to caller diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 00363c7ac182..28eb410ca779 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -676,7 +676,8 @@ static struct pxa2xx_udc_mach_info zeus_udc_info = { static void zeus_power_off(void) { local_irq_disable(); - pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET); + cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, PWRMODE_DEEPSLEEP, + pxa27x_finish_suspend); } #else #define zeus_power_off NULL -- cgit v1.2.3 From 857c1b81f8dd2e2a97d859d7e53dd955e2ab55af Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 22 Jun 2011 12:44:32 +0100 Subject: ARM: pm: omap34xx: no need to save all registers in sleep34xx.S The ABI allows called functions to corrupt r0-r3 and ip (r12). So its pointless saving these registers in the suspend code - the calling function will expect them to be corrupted and so won't rely on their contents after resume. Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman Acked-by: Jean Pihet Signed-off-by: Russell King --- arch/arm/mach-omap2/sleep34xx.S | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 63f10669571a..9551c7dc71ef 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -133,7 +133,7 @@ ENDPROC(enable_omap3630_toggle_l2_on_restore) /* Function to call rom code to save secure ram context */ .align 3 ENTRY(save_secure_ram_context) - stmfd sp!, {r1-r12, lr} @ save registers on stack + stmfd sp!, {r4 - r11, lr} @ save registers on stack adr r3, api_params @ r3 points to parameters str r0, [r3,#0x4] @ r0