[PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support

Frank Hofmann frank.hofmann at tomtom.com
Mon Feb 7 10:41:38 EST 2011


Hi,

Russell's suspend/resume patch is a great way to make the Hibernation code 
generic - and utterly simple. See below.

> diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
> index 6980215..8ec535e 100644
> --- a/arch/arm/include/asm/proc-fns.h
> +++ b/arch/arm/include/asm/proc-fns.h
> @@ -66,6 +66,11 @@ extern struct processor {
> 	 * ignore 'ext'.
> 	 */
> 	void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
> +
> +	/* Suspend/resume */
> +	unsigned int suspend_size;
> +	void (*do_suspend)(void *);
> +	void (*do_resume)(void *);
> } processor;


These seem to do exactly what the various hibernation patches try to 
perform in __save/__restore_processor_state() - takes a buffer to 
(re)store the world to/from. Having it there allows to ditch the 
hibernation patch monstrosity.


The ARM hibernation patch would then simply become these two files:

arch/arm/include/asm/suspend.h will look like:

=====================================================================
#ifndef __ASM_ARM_SUSPEND_H
#define __ASM_ARM_SUSPEND_H

static inline int arch_prepare_suspend(void) { return 0; }

#define save_processor_state    preempt_disable
#define restore_processor_state preempt_enable

#endif  /* __ASM_ARM_SUSPEND_H */
=====================================================================


and arch/arm/kernel/swsusp.S will be:
=====================================================================
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/cache.h>
#include <asm/memory.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/ptrace.h>

/*
  * Force arm mode because this uses immediate msr.
  */
.arm

#define	REGS_USR	(0)
#define	REGS_SVC	(REGS_USR + 16 * 4)

ENTRY(swsusp_arch_suspend)
 	ldr	r0, =saved_processor_state	/* wherever that is */
 	mrs	r1, cpsr
 	stm	r0!, {r1}		/* current CPSR */
 	msr	cpsr_c, #SYSTEM_MODE
 	stm	r0!, {r0-r14}		/* user regs */
 	msr	cpsr_c, #SVC_MODE
 	mrs	r2, spsr
 	stm	r0!, {r2, sp, lr}	/* SVC SPSR, SVC regs */
 	msr	cpsr, r1		/* restore original mode */

 	ldr	r1, =procfns
 	mov	lr, pc
 	ldr	pc, [r1, #CPU_DO_SUSPEND]

 	bl	swsusp_save
 	mov	r0, #0
 	ldr	r1, =saved_processor_state
 	ldr	lr, [r1, REGS_SVC + 8]
 	bx	lr
ENDPROC(swsusp_arch_suspend)


ENTRY(swsusp_arch_resume)
/* page copy loop omitted for brevity */
 	msr	cpsr_c, #SYSTEM_MODE
 	ldr	r0, =saved_processor_state
 	ldm	r0!, {r1, sp, lr}	/* first word is CPSR, following are r0/r1 (irrelevant) */
 	msr	cpsr_cxsf, r1
 	ldm	r0!, {r2-r14}
 	msr	cpsr_c, #SVC_MODE
 	ldm	r0!, {r2, sp, lr}
 	msr	spsr_cxsf, r2
 	msr	cpsr_c, r1		/* use CPSR from above */

 	bl	local_flush_tlb_all

 	ldr	r1, =procfns
 	mov	lr, pc
 	ldr	pc, [r1, #CPU_DO_RESUME]
 	mov	r0, #0
 	ldr	r1, =saved_processor_state
 	ldr	lr, [r1, REGS_SVC + 8]
 	bx	lr

ENDPROC(swsusp_arch_resume)
=====================================================================



It'll be a few days before I can test this properly, need to get Russell's 
changes into our (not exactly mainline) local tree first. I'll report on 
the progress.


Thanks !
FrankH.



More information about the linux-arm-kernel mailing list