aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorWu Zhangjin <wuzj@lemote.com>2009-06-04 08:27:10 -0400
committerRalf Baechle <ralf@linux-mips.org>2009-06-17 06:06:31 -0400
commit363c55cae53742f3f685a1814912c6d4fda245b4 (patch)
tree3be662ed49bbc90c80c9faa5e71176209989d2ea /arch/mips
parent4bb1a1089e321d685967032497f4363081eab3a9 (diff)
MIPS: Add hibernation support
[Ralf: SMP support requires CPU hotplugging which MIPS currently doesn't support. As implemented in this patch cache and tlb flushing will also be invoked with interrupts disabled so smp_call_function() will blow up in charming ways. So limit to !SMP.] Reviewed-by: Pavel Machek <pavel@ucw.cz> Reviewed-by: Yan Hua <yanh@lemote.com> Reviewed-by: Arnaud Patard <apatard@mandriva.com> Reviewed-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Wu Zhangjin <wuzj@lemote.com> Signed-off-by: Hu Hongbing <huhb@lemote.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Kconfig4
-rw-r--r--arch/mips/Makefile3
-rw-r--r--arch/mips/include/asm/suspend.h9
-rw-r--r--arch/mips/kernel/asm-offsets.c13
-rw-r--r--arch/mips/power/Makefile1
-rw-r--r--arch/mips/power/cpu.c43
-rw-r--r--arch/mips/power/hibernate.S70
7 files changed, 143 insertions, 0 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index cebebf151a14..b29f0280d712 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2134,6 +2134,10 @@ endmenu
2134 2134
2135menu "Power management options" 2135menu "Power management options"
2136 2136
2137config ARCH_HIBERNATION_POSSIBLE
2138 def_bool y
2139 depends on !SMP
2140
2137config ARCH_SUSPEND_POSSIBLE 2141config ARCH_SUSPEND_POSSIBLE
2138 def_bool y 2142 def_bool y
2139 depends on !SMP 2143 depends on !SMP
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index e5ccc3490d6a..807572a6a4d2 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -677,6 +677,9 @@ core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/
677 677
678drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/ 678drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/
679 679
680# suspend and hibernation support
681drivers-$(CONFIG_PM) += arch/mips/power/
682
680ifdef CONFIG_LASAT 683ifdef CONFIG_LASAT
681rom.bin rom.sw: vmlinux 684rom.bin rom.sw: vmlinux
682 $(Q)$(MAKE) $(build)=arch/mips/lasat/image $@ 685 $(Q)$(MAKE) $(build)=arch/mips/lasat/image $@
diff --git a/arch/mips/include/asm/suspend.h b/arch/mips/include/asm/suspend.h
new file mode 100644
index 000000000000..294cdb66c5fc
--- /dev/null
+++ b/arch/mips/include/asm/suspend.h
@@ -0,0 +1,9 @@
1#ifndef __ASM_SUSPEND_H
2#define __ASM_SUSPEND_H
3
4static inline int arch_prepare_suspend(void) { return 0; }
5
6/* References to section boundaries */
7extern const void __nosave_begin, __nosave_end;
8
9#endif /* __ASM_SUSPEND_H */
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index c901c22d7ad0..8d006ec65677 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -14,6 +14,7 @@
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/kbuild.h> 16#include <linux/kbuild.h>
17#include <linux/suspend.h>
17#include <asm/ptrace.h> 18#include <asm/ptrace.h>
18#include <asm/processor.h> 19#include <asm/processor.h>
19 20
@@ -326,3 +327,15 @@ void output_octeon_cop2_state_defines(void)
326 BLANK(); 327 BLANK();
327} 328}
328#endif 329#endif
330
331#ifdef CONFIG_HIBERNATION
332void output_pbe_defines(void)
333{
334 COMMENT(" Linux struct pbe offsets. ");
335 OFFSET(PBE_ADDRESS, pbe, address);
336 OFFSET(PBE_ORIG_ADDRESS, pbe, orig_address);
337 OFFSET(PBE_NEXT, pbe, next);
338 DEFINE(PBE_SIZE, sizeof(struct pbe));
339 BLANK();
340}
341#endif
diff --git a/arch/mips/power/Makefile b/arch/mips/power/Makefile
new file mode 100644
index 000000000000..73d56b87cb9b
--- /dev/null
+++ b/arch/mips/power/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_HIBERNATION) += cpu.o hibernate.o
diff --git a/arch/mips/power/cpu.c b/arch/mips/power/cpu.c
new file mode 100644
index 000000000000..7995df45dc8d
--- /dev/null
+++ b/arch/mips/power/cpu.c
@@ -0,0 +1,43 @@
1/*
2 * Suspend support specific for mips.
3 *
4 * Licensed under the GPLv2
5 *
6 * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
7 * Author: Hu Hongbing <huhb@lemote.com>
8 * Wu Zhangjin <wuzj@lemote.com>
9 */
10#include <asm/suspend.h>
11#include <asm/fpu.h>
12#include <asm/dsp.h>
13
14static u32 saved_status;
15struct pt_regs saved_regs;
16
17void save_processor_state(void)
18{
19 saved_status = read_c0_status();
20
21 if (is_fpu_owner())
22 save_fp(current);
23 if (cpu_has_dsp)
24 save_dsp(current);
25}
26
27void restore_processor_state(void)
28{
29 write_c0_status(saved_status);
30
31 if (is_fpu_owner())
32 restore_fp(current);
33 if (cpu_has_dsp)
34 restore_dsp(current);
35}
36
37int pfn_is_nosave(unsigned long pfn)
38{
39 unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin));
40 unsigned long nosave_end_pfn = PFN_UP(__pa(&__nosave_end));
41
42 return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
43}
diff --git a/arch/mips/power/hibernate.S b/arch/mips/power/hibernate.S
new file mode 100644
index 000000000000..486bd3fd01a1
--- /dev/null
+++ b/arch/mips/power/hibernate.S
@@ -0,0 +1,70 @@
1/*
2 * Hibernation support specific for mips - temporary page tables
3 *
4 * Licensed under the GPLv2
5 *
6 * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
7 * Author: Hu Hongbing <huhb@lemote.com>
8 * Wu Zhangjin <wuzj@lemote.com>
9 */
10#include <asm/asm-offsets.h>
11#include <asm/regdef.h>
12#include <asm/asm.h>
13
14.text
15LEAF(swsusp_arch_suspend)
16 PTR_LA t0, saved_regs
17 PTR_S ra, PT_R31(t0)
18 PTR_S sp, PT_R29(t0)
19 PTR_S fp, PT_R30(t0)
20 PTR_S gp, PT_R28(t0)
21 PTR_S s0, PT_R16(t0)
22 PTR_S s1, PT_R17(t0)
23 PTR_S s2, PT_R18(t0)
24 PTR_S s3, PT_R19(t0)
25 PTR_S s4, PT_R20(t0)
26 PTR_S s5, PT_R21(t0)
27 PTR_S s6, PT_R22(t0)
28 PTR_S s7, PT_R23(t0)
29 j swsusp_save
30END(swsusp_arch_suspend)
31
32LEAF(swsusp_arch_resume)
33 PTR_L t0, restore_pblist
340:
35 PTR_L t1, PBE_ADDRESS(t0) /* source */
36 PTR_L t2, PBE_ORIG_ADDRESS(t0) /* destination */
37 PTR_ADDIU t3, t1, _PAGE_SIZE
381:
39 REG_L t8, (t1)
40 REG_S t8, (t2)
41 PTR_ADDIU t1, t1, SZREG
42 PTR_ADDIU t2, t2, SZREG
43 bne t1, t3, 1b
44 PTR_L t0, PBE_NEXT(t0)
45 bnez t0, 0b
46 /* flush caches to make sure context is in memory */
47 PTR_L t0, __flush_cache_all
48 jalr t0
49 /* flush tlb entries */
50#ifdef CONFIG_SMP
51 jal flush_tlb_all
52#else
53 jal local_flush_tlb_all
54#endif
55 PTR_LA t0, saved_regs
56 PTR_L ra, PT_R31(t0)
57 PTR_L sp, PT_R29(t0)
58 PTR_L fp, PT_R30(t0)
59 PTR_L gp, PT_R28(t0)
60 PTR_L s0, PT_R16(t0)
61 PTR_L s1, PT_R17(t0)
62 PTR_L s2, PT_R18(t0)
63 PTR_L s3, PT_R19(t0)
64 PTR_L s4, PT_R20(t0)
65 PTR_L s5, PT_R21(t0)
66 PTR_L s6, PT_R22(t0)
67 PTR_L s7, PT_R23(t0)
68 PTR_LI v0, 0x0
69 jr ra
70END(swsusp_arch_resume)