 2ef7f0dab6
			
		
	
	
	2ef7f0dab6
	
	
	
		
			
			Add Suspend-to-disk / swsusp / CONFIG_HIBERNATION support to the SuperH architecture. To suspend, use "swapon /dev/sda2; echo disk > /sys/power/state" To resume, pass "resume=/dev/sda2" on the kernel command line. The patch "pm: rework includes, remove arch ifdefs V2" is needed to allow the generic swsusp code to build properly. Hibernation is not enabled with this patch though, a patch setting ARCH_HIBERNATION_POSSIBLE will be submitted later. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
		
			
				
	
	
		
			147 lines
		
	
	
	
		
			2.9 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			147 lines
		
	
	
	
		
			2.9 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * arch/sh/kernel/cpu/sh3/swsusp.S
 | |
|  *
 | |
|  * Copyright (C) 2009 Magnus Damm
 | |
|  *
 | |
|  * This file is subject to the terms and conditions of the GNU General Public
 | |
|  * License.  See the file "COPYING" in the main directory of this archive
 | |
|  * for more details.
 | |
|  */
 | |
| #include <linux/sys.h>
 | |
| #include <linux/errno.h>
 | |
| #include <linux/linkage.h>
 | |
| #include <asm/asm-offsets.h>
 | |
| #include <asm/page.h>
 | |
| 
 | |
| #define k0	r0
 | |
| #define k1	r1
 | |
| #define k2	r2
 | |
| #define k3	r3
 | |
| #define k4	r4
 | |
| 
 | |
| ! swsusp_arch_resume()
 | |
| ! - copy restore_pblist pages
 | |
| ! - restore registers from swsusp_arch_regs_cpu0
 | |
| 
 | |
| ENTRY(swsusp_arch_resume)
 | |
| 	mov.l	1f, r15
 | |
| 	mov.l	2f, r4
 | |
| 	mov.l	@r4, r4
 | |
| 
 | |
| swsusp_copy_loop:
 | |
| 	mov	r4, r0
 | |
| 	cmp/eq	#0, r0
 | |
| 	bt	swsusp_restore_regs
 | |
| 
 | |
| 	mov.l	@(PBE_ADDRESS, r4), r2
 | |
| 	mov.l	@(PBE_ORIG_ADDRESS, r4), r5
 | |
| 
 | |
| 	mov	#(PAGE_SIZE >> 10), r3
 | |
| 	shll8	r3
 | |
| 	shlr2	r3 /* PAGE_SIZE / 16 */
 | |
| swsusp_copy_page:
 | |
| 	dt	r3
 | |
| 	mov.l	@r2+,r1   /*  16n+0 */
 | |
| 	mov.l	r1,@r5
 | |
| 	add	#4,r5
 | |
| 	mov.l	@r2+,r1	  /*  16n+4 */
 | |
| 	mov.l	r1,@r5
 | |
| 	add	#4,r5
 | |
| 	mov.l	@r2+,r1   /*  16n+8 */
 | |
| 	mov.l	r1,@r5
 | |
| 	add	#4,r5
 | |
| 	mov.l	@r2+,r1   /*  16n+12 */
 | |
| 	mov.l	r1,@r5
 | |
| 	bf/s	swsusp_copy_page
 | |
| 	 add	#4,r5
 | |
| 
 | |
| 	bra	swsusp_copy_loop
 | |
| 	 mov.l	@(PBE_NEXT, r4), r4
 | |
| 
 | |
| swsusp_restore_regs:
 | |
| 	! BL=0: R7->R0 is bank0
 | |
| 	mov.l	3f, r8
 | |
| 	mov.l	4f, r5
 | |
| 	jsr	@r5
 | |
| 	 nop
 | |
| 
 | |
| 	! BL=1: R7->R0 is bank1
 | |
| 	lds	k2, pr
 | |
| 	ldc	k3, ssr
 | |
| 
 | |
| 	mov.l	@r15+, r0
 | |
| 	mov.l	@r15+, r1
 | |
| 	mov.l	@r15+, r2
 | |
| 	mov.l	@r15+, r3
 | |
| 	mov.l	@r15+, r4
 | |
| 	mov.l	@r15+, r5
 | |
| 	mov.l	@r15+, r6
 | |
| 	mov.l	@r15+, r7
 | |
| 
 | |
| 	rte
 | |
| 	 nop
 | |
| 	! BL=0: R7->R0 is bank0
 | |
| 
 | |
| 	.align	2
 | |
| 1:	.long	swsusp_arch_regs_cpu0
 | |
| 2:	.long	restore_pblist
 | |
| 3:	.long	0x20000000 ! RB=1
 | |
| 4:	.long	restore_regs
 | |
| 
 | |
| ! swsusp_arch_suspend()
 | |
| ! - prepare pc for resume, return from function without swsusp_save on resume
 | |
| ! - save registers in swsusp_arch_regs_cpu0
 | |
| ! - call swsusp_save write suspend image
 | |
| 
 | |
| ENTRY(swsusp_arch_suspend)
 | |
| 	sts	pr, r0		! save pr in r0
 | |
| 	mov	r15, r2		! save sp in r2
 | |
| 	mov	r8, r5		! save r8 in r5
 | |
| 	stc	sr, r1
 | |
| 	ldc	r1, ssr		! save sr in ssr
 | |
| 	mov.l	1f, r1
 | |
| 	ldc	r1, spc		! setup pc value for resuming
 | |
| 	mov.l	5f, r15		! use swsusp_arch_regs_cpu0 as stack
 | |
| 	mov.l	6f, r3
 | |
| 	add	r3, r15		! save from top of structure
 | |
| 
 | |
| 	! BL=0: R7->R0 is bank0
 | |
| 	mov.l	2f, r3		! get new SR value for bank1
 | |
| 	mov	#0, r4
 | |
| 	mov.l	7f, r1
 | |
| 	jsr	@r1		! switch to bank1 and save bank1 r7->r0
 | |
| 	 not	r4, r4
 | |
| 
 | |
| 	! BL=1: R7->R0 is bank1
 | |
| 	stc	r2_bank, k0	! fetch old sp from r2_bank0
 | |
| 	mov.l	3f, k4		! SR bits to clear in k4
 | |
| 	mov.l	8f, k1
 | |
| 	jsr	@k1		! switch to bank0 and save all regs
 | |
| 	 stc	r0_bank, k3	! fetch old pr from r0_bank0
 | |
| 
 | |
| 	! BL=0: R7->R0 is bank0
 | |
| 	mov	r2, r15		! restore old sp
 | |
| 	mov	r5, r8		! restore old r8
 | |
| 	stc	ssr, r1
 | |
| 	ldc	r1, sr		! restore old sr
 | |
| 	lds	r0, pr		! restore old pr
 | |
| 	mov.l	4f, r0
 | |
| 	jmp	@r0
 | |
| 	 nop
 | |
| 
 | |
| swsusp_call_save:
 | |
| 	mov	r2, r15		! restore old sp
 | |
| 	mov	r5, r8		! restore old r8
 | |
| 	lds	r0, pr		! restore old pr
 | |
| 	rts
 | |
| 	 mov	#0, r0
 | |
| 
 | |
| 	.align	2
 | |
| 1:	.long	swsusp_call_save
 | |
| 2:	.long	0x20000000 ! RB=1
 | |
| 3:	.long	0xdfffffff ! RB=0
 | |
| 4:	.long	swsusp_save
 | |
| 5:	.long	swsusp_arch_regs_cpu0
 | |
| 6:	.long	SWSUSP_ARCH_REGS_SIZE
 | |
| 7:	.long	save_low_regs
 | |
| 8:	.long	save_regs
 |