-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Magnus Damm
authored and
Paul Mundt
committed
Mar 10, 2009
1 parent
edab56f
commit 2ef7f0d
Showing
9 changed files
with
228 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#ifndef _ASM_SH_SUSPEND_H | ||
#define _ASM_SH_SUSPEND_H | ||
|
||
static inline int arch_prepare_suspend(void) { return 0; } | ||
|
||
#include <asm/ptrace.h> | ||
|
||
struct swsusp_arch_regs { | ||
struct pt_regs user_regs; | ||
unsigned long bank1_regs[8]; | ||
}; | ||
|
||
#endif /* _ASM_SH_SUSPEND_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
/* | ||
* 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* swsusp.c - SuperH hibernation support | ||
* | ||
* 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/mm.h> | ||
#include <linux/sched.h> | ||
#include <linux/suspend.h> | ||
#include <asm/suspend.h> | ||
#include <asm/sections.h> | ||
#include <asm/tlbflush.h> | ||
#include <asm/page.h> | ||
#include <asm/fpu.h> | ||
|
||
struct swsusp_arch_regs swsusp_arch_regs_cpu0; | ||
|
||
int pfn_is_nosave(unsigned long pfn) | ||
{ | ||
unsigned long begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; | ||
unsigned long end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT; | ||
|
||
return (pfn >= begin_pfn) && (pfn < end_pfn); | ||
} | ||
|
||
void save_processor_state(void) | ||
{ | ||
init_fpu(current); | ||
} | ||
|
||
void restore_processor_state(void) | ||
{ | ||
local_flush_tlb_all(); | ||
} |