aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/power
diff options
context:
space:
mode:
authorTkhai Kirill <tkhai@yandex.ru>2013-03-19 11:11:07 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-20 14:06:54 -0400
commitbdde6b3c8ba48fa5847b6d75f0541c8b8db9205c (patch)
tree9fccf29eca02be11f5e6e9eec13ae6d056ff3288 /arch/sparc/power
parent1ab0a67601ca7be81bfaaa0a2540ee0d0393f40b (diff)
sparc64: Hibernation support
This patch adds CONFIG_HIBERNATION support for sparc64 architecture. The suspend function is the same as on another platforms. The restore function uses Bypass feature of MMU which allows to make the process more comfortable and plesant. Signed-off-by: Kirill Tkhai <tkhai@yandex.ru> CC: David Miller <davem@davemloft.net> CC: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/power')
-rw-r--r--arch/sparc/power/Makefile3
-rw-r--r--arch/sparc/power/hibernate.c42
-rw-r--r--arch/sparc/power/hibernate_asm.S131
3 files changed, 176 insertions, 0 deletions
diff --git a/arch/sparc/power/Makefile b/arch/sparc/power/Makefile
new file mode 100644
index 000000000000..3201ace0ddbd
--- /dev/null
+++ b/arch/sparc/power/Makefile
@@ -0,0 +1,3 @@
1# Makefile for Sparc-specific hibernate files.
2
3obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate_asm.o
diff --git a/arch/sparc/power/hibernate.c b/arch/sparc/power/hibernate.c
new file mode 100644
index 000000000000..42b0b8ce699a
--- /dev/null
+++ b/arch/sparc/power/hibernate.c
@@ -0,0 +1,42 @@
1/*
2 * hibernate.c: Hibernaton support specific for sparc64.
3 *
4 * Copyright (C) 2013 Kirill V Tkhai (tkhai@yandex.ru)
5 */
6
7#include <linux/mm.h>
8
9#include <asm/hibernate.h>
10#include <asm/visasm.h>
11#include <asm/page.h>
12#include <asm/tlb.h>
13
14/* References to section boundaries */
15extern const void __nosave_begin, __nosave_end;
16
17struct saved_context saved_context;
18
19/*
20 * pfn_is_nosave - check if given pfn is in the 'nosave' section
21 */
22
23int pfn_is_nosave(unsigned long pfn)
24{
25 unsigned long nosave_begin_pfn = PFN_DOWN((unsigned long)&__nosave_begin);
26 unsigned long nosave_end_pfn = PFN_DOWN((unsigned long)&__nosave_end);
27
28 return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
29}
30
31void save_processor_state(void)
32{
33 save_and_clear_fpu();
34}
35
36void restore_processor_state(void)
37{
38 struct mm_struct *mm = current->active_mm;
39
40 load_secondary_context(mm);
41 tsb_context_switch(mm);
42}
diff --git a/arch/sparc/power/hibernate_asm.S b/arch/sparc/power/hibernate_asm.S
new file mode 100644
index 000000000000..79942166df84
--- /dev/null
+++ b/arch/sparc/power/hibernate_asm.S
@@ -0,0 +1,131 @@
1/*
2 * hibernate_asm.S: Hibernaton support specific for sparc64.
3 *
4 * Copyright (C) 2013 Kirill V Tkhai (tkhai@yandex.ru)
5 */
6
7#include <linux/linkage.h>
8
9#include <asm/asm-offsets.h>
10#include <asm/cpudata.h>
11#include <asm/page.h>
12
13ENTRY(swsusp_arch_suspend)
14 save %sp, -128, %sp
15 save %sp, -128, %sp
16 flushw
17
18 setuw saved_context, %g3
19
20 /* Save window regs */
21 rdpr %cwp, %g2
22 stx %g2, [%g3 + SC_REG_CWP]
23 rdpr %wstate, %g2
24 stx %g2, [%g3 + SC_REG_WSTATE]
25 stx %fp, [%g3 + SC_REG_FP]
26
27 /* Save state regs */
28 rdpr %tick, %g2
29 stx %g2, [%g3 + SC_REG_TICK]
30 rdpr %pstate, %g2
31 stx %g2, [%g3 + SC_REG_PSTATE]
32
33 /* Save global regs */
34 stx %g4, [%g3 + SC_REG_G4]
35 stx %g5, [%g3 + SC_REG_G5]
36 stx %g6, [%g3 + SC_REG_G6]
37
38 call swsusp_save
39 nop
40
41 mov %o0, %i0
42 restore
43
44 mov %o0, %i0
45 ret
46 restore
47
48ENTRY(swsusp_arch_resume)
49 /* Write restore_pblist to %l0 */
50 sethi %hi(restore_pblist), %l0
51 ldx [%l0 + %lo(restore_pblist)], %l0
52
53 call __flush_tlb_all
54 nop
55
56 /* Write PAGE_OFFSET to %g7 */
57 sethi %uhi(PAGE_OFFSET), %g7
58 sllx %g7, 32, %g7
59
60 setuw (PAGE_SIZE-8), %g3
61
62 /* Use MMU Bypass */
63 rd %asi, %g1
64 wr %g0, ASI_PHYS_USE_EC, %asi
65
66 ba fill_itlb
67 nop
68
69pbe_loop:
70 cmp %l0, %g0
71 be restore_ctx
72 sub %l0, %g7, %l0
73
74 ldxa [%l0 ] %asi, %l1 /* address */
75 ldxa [%l0 + 8] %asi, %l2 /* orig_address */
76
77 /* phys addr */
78 sub %l1, %g7, %l1
79 sub %l2, %g7, %l2
80
81 mov %g3, %l3 /* PAGE_SIZE-8 */
82copy_loop:
83 ldxa [%l1 + %l3] ASI_PHYS_USE_EC, %g2
84 stxa %g2, [%l2 + %l3] ASI_PHYS_USE_EC
85 cmp %l3, %g0
86 bne copy_loop
87 sub %l3, 8, %l3
88
89 /* next pbe */
90 ba pbe_loop
91 ldxa [%l0 + 16] %asi, %l0
92
93restore_ctx:
94 setuw saved_context, %g3
95
96 /* Restore window regs */
97 wrpr %g0, 0, %canrestore
98 wrpr %g0, 0, %otherwin
99 wrpr %g0, 6, %cansave
100 wrpr %g0, 0, %cleanwin
101
102 ldxa [%g3 + SC_REG_CWP] %asi, %g2
103 wrpr %g2, %cwp
104 ldxa [%g3 + SC_REG_WSTATE] %asi, %g2
105 wrpr %g2, %wstate
106 ldxa [%g3 + SC_REG_FP] %asi, %fp
107
108 /* Restore state regs */
109 ldxa [%g3 + SC_REG_PSTATE] %asi, %g2
110 wrpr %g2, %pstate
111 ldxa [%g3 + SC_REG_TICK] %asi, %g2
112 wrpr %g2, %tick
113
114 /* Restore global regs */
115 ldxa [%g3 + SC_REG_G4] %asi, %g4
116 ldxa [%g3 + SC_REG_G5] %asi, %g5
117 ldxa [%g3 + SC_REG_G6] %asi, %g6
118
119 wr %g1, %g0, %asi
120
121 restore
122 restore
123
124 wrpr %g0, 14, %pil
125
126 retl
127 mov %g0, %o0
128
129fill_itlb:
130 ba pbe_loop
131 wrpr %g0, 15, %pil