diff options
author | Magnus Damm <damm@opensource.se> | 2010-02-25 06:03:24 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-02-26 01:29:26 -0500 |
commit | 41bfb7d7a6ce3d8dd83112e65f5d97feefde818a (patch) | |
tree | fc0b6c2430c30aac82377143a364a64967511813 /arch/sh/kernel/cpu/shmobile/sleep.S | |
parent | da64c2a8dee66ca03f4f3e15d84be7bedf73db3d (diff) |
sh: SH-Mobile R-standby register save/restore
Add code to save/restore registers during
R-standby sleep on SH-Mobile processors.
Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/cpu/shmobile/sleep.S')
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/sleep.S | 121 |
1 files changed, 119 insertions, 2 deletions
diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S index e9dd7fa0abd2..e6aac65f5750 100644 --- a/arch/sh/kernel/cpu/shmobile/sleep.S +++ b/arch/sh/kernel/cpu/shmobile/sleep.S | |||
@@ -48,8 +48,48 @@ ENTRY(sh_mobile_sleep_enter_start) | |||
48 | stc sr, r0 | 48 | stc sr, r0 |
49 | mov.l r0, @(SH_SLEEP_SR, r5) | 49 | mov.l r0, @(SH_SLEEP_SR, r5) |
50 | 50 | ||
51 | /* save sp */ | 51 | /* save general purpose registers to stack if needed */ |
52 | mov.l @(SH_SLEEP_MODE, r5), r0 | ||
53 | tst #SUSP_SH_REGS, r0 | ||
54 | bt skip_regs_save | ||
55 | |||
56 | sts.l pr, @-r15 | ||
57 | mov.l r14, @-r15 | ||
58 | mov.l r13, @-r15 | ||
59 | mov.l r12, @-r15 | ||
60 | mov.l r11, @-r15 | ||
61 | mov.l r10, @-r15 | ||
62 | mov.l r9, @-r15 | ||
63 | mov.l r8, @-r15 | ||
64 | |||
65 | /* make sure bank0 is selected, save low registers */ | ||
66 | mov.l rb_bit, r9 | ||
67 | not r9, r9 | ||
68 | bsr set_sr | ||
69 | mov #0, r10 | ||
70 | |||
71 | bsr save_low_regs | ||
72 | nop | ||
73 | |||
74 | /* switch to bank 1, save low registers */ | ||
75 | mov.l rb_bit, r10 | ||
76 | bsr set_sr | ||
77 | mov #-1, r9 | ||
78 | |||
79 | bsr save_low_regs | ||
80 | nop | ||
81 | |||
82 | /* switch back to bank 0 */ | ||
83 | mov.l rb_bit, r9 | ||
84 | not r9, r9 | ||
85 | bsr set_sr | ||
86 | mov #0, r10 | ||
87 | |||
88 | skip_regs_save: | ||
89 | |||
90 | /* save sp, also set to internal ram */ | ||
52 | mov.l r15, @(SH_SLEEP_SP, r5) | 91 | mov.l r15, @(SH_SLEEP_SP, r5) |
92 | mov r5, r15 | ||
53 | 93 | ||
54 | /* save stbcr */ | 94 | /* save stbcr */ |
55 | bsr save_register | 95 | bsr save_register |
@@ -60,7 +100,7 @@ ENTRY(sh_mobile_sleep_enter_start) | |||
60 | tst #SUSP_SH_MMU, r0 | 100 | tst #SUSP_SH_MMU, r0 |
61 | bt skip_mmu_save_disable | 101 | bt skip_mmu_save_disable |
62 | 102 | ||
63 | /* save mmu state */ | 103 | /* save mmu state */ |
64 | bsr save_register | 104 | bsr save_register |
65 | mov #SH_SLEEP_REG_PTEH, r0 | 105 | mov #SH_SLEEP_REG_PTEH, r0 |
66 | 106 | ||
@@ -177,6 +217,29 @@ get_register: | |||
177 | mov.l @(r0, r5), r0 | 217 | mov.l @(r0, r5), r0 |
178 | rts | 218 | rts |
179 | nop | 219 | nop |
220 | |||
221 | set_sr: | ||
222 | stc sr, r8 | ||
223 | and r9, r8 | ||
224 | or r10, r8 | ||
225 | ldc r8, sr | ||
226 | rts | ||
227 | nop | ||
228 | |||
229 | save_low_regs: | ||
230 | mov.l r7, @-r15 | ||
231 | mov.l r6, @-r15 | ||
232 | mov.l r5, @-r15 | ||
233 | mov.l r4, @-r15 | ||
234 | mov.l r3, @-r15 | ||
235 | mov.l r2, @-r15 | ||
236 | mov.l r1, @-r15 | ||
237 | rts | ||
238 | mov.l r0, @-r15 | ||
239 | |||
240 | .balign 4 | ||
241 | rb_bit: .long 0x20000000 ! RB=1 | ||
242 | |||
180 | ENTRY(sh_mobile_sleep_enter_end) | 243 | ENTRY(sh_mobile_sleep_enter_end) |
181 | 244 | ||
182 | .balign 4 | 245 | .balign 4 |
@@ -270,6 +333,40 @@ skip_restore_sf: | |||
270 | icbi @r0 | 333 | icbi @r0 |
271 | 334 | ||
272 | skip_restore_mmu: | 335 | skip_restore_mmu: |
336 | |||
337 | /* restore general purpose registers if needed */ | ||
338 | mov.l @(SH_SLEEP_MODE, r5), r0 | ||
339 | tst #SUSP_SH_REGS, r0 | ||
340 | bt skip_restore_regs | ||
341 | |||
342 | /* switch to bank 1, restore low registers */ | ||
343 | mov.l _rb_bit, r10 | ||
344 | bsr _set_sr | ||
345 | mov #-1, r9 | ||
346 | |||
347 | bsr restore_low_regs | ||
348 | nop | ||
349 | |||
350 | /* switch to bank0, restore low registers */ | ||
351 | mov.l _rb_bit, r9 | ||
352 | not r9, r9 | ||
353 | bsr _set_sr | ||
354 | mov #0, r10 | ||
355 | |||
356 | bsr restore_low_regs | ||
357 | nop | ||
358 | |||
359 | /* restore the rest of the registers */ | ||
360 | mov.l @r15+, r8 | ||
361 | mov.l @r15+, r9 | ||
362 | mov.l @r15+, r10 | ||
363 | mov.l @r15+, r11 | ||
364 | mov.l @r15+, r12 | ||
365 | mov.l @r15+, r13 | ||
366 | mov.l @r15+, r14 | ||
367 | lds.l @r15+, pr | ||
368 | |||
369 | skip_restore_regs: | ||
273 | rte | 370 | rte |
274 | nop | 371 | nop |
275 | 372 | ||
@@ -283,6 +380,26 @@ restore_register: | |||
283 | rts | 380 | rts |
284 | nop | 381 | nop |
285 | 382 | ||
383 | _set_sr: | ||
384 | stc sr, r8 | ||
385 | and r9, r8 | ||
386 | or r10, r8 | ||
387 | ldc r8, sr | ||
388 | rts | ||
389 | nop | ||
390 | |||
391 | restore_low_regs: | ||
392 | mov.l @r15+, r0 | ||
393 | mov.l @r15+, r1 | ||
394 | mov.l @r15+, r2 | ||
395 | mov.l @r15+, r3 | ||
396 | mov.l @r15+, r4 | ||
397 | mov.l @r15+, r5 | ||
398 | mov.l @r15+, r6 | ||
399 | rts | ||
400 | mov.l @r15+, r7 | ||
401 | |||
286 | .balign 4 | 402 | .balign 4 |
403 | _rb_bit: .long 0x20000000 ! RB=1 | ||
287 | 1: .long ~0x7ff | 404 | 1: .long ~0x7ff |
288 | ENTRY(sh_mobile_sleep_resume_end) | 405 | ENTRY(sh_mobile_sleep_resume_end) |