diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/sh/include/asm/suspend.h | 1 | ||||
| -rw-r--r-- | arch/sh/kernel/cpu/shmobile/pm.c | 3 | ||||
| -rw-r--r-- | arch/sh/kernel/cpu/shmobile/sleep.S | 121 |
3 files changed, 122 insertions, 3 deletions
diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h index fe9c2a1ad047..64eb41a063e8 100644 --- a/arch/sh/include/asm/suspend.h +++ b/arch/sh/include/asm/suspend.h | |||
| @@ -92,5 +92,6 @@ extern unsigned long sh_mobile_sleep_supported; | |||
| 92 | #define SUSP_SH_USTANDBY (1 << 3) /* SH-Mobile U-standby mode */ | 92 | #define SUSP_SH_USTANDBY (1 << 3) /* SH-Mobile U-standby mode */ |
| 93 | #define SUSP_SH_SF (1 << 4) /* Enable self-refresh */ | 93 | #define SUSP_SH_SF (1 << 4) /* Enable self-refresh */ |
| 94 | #define SUSP_SH_MMU (1 << 5) /* Save/restore MMU and cache */ | 94 | #define SUSP_SH_MMU (1 << 5) /* Save/restore MMU and cache */ |
| 95 | #define SUSP_SH_REGS (1 << 6) /* Save/restore registers */ | ||
| 95 | 96 | ||
| 96 | #endif /* _ASM_SH_SUSPEND_H */ | 97 | #endif /* _ASM_SH_SUSPEND_H */ |
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c index ca029a44743c..e55968712706 100644 --- a/arch/sh/kernel/cpu/shmobile/pm.c +++ b/arch/sh/kernel/cpu/shmobile/pm.c | |||
| @@ -33,7 +33,8 @@ ATOMIC_NOTIFIER_HEAD(sh_mobile_post_sleep_notifier_list); | |||
| 33 | #define SUSP_MODE_SLEEP (SUSP_SH_SLEEP) | 33 | #define SUSP_MODE_SLEEP (SUSP_SH_SLEEP) |
| 34 | #define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF) | 34 | #define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF) |
| 35 | #define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF) | 35 | #define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF) |
| 36 | #define SUSP_MODE_RSTANDBY (SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_SF) | 36 | #define SUSP_MODE_RSTANDBY_SF \ |
| 37 | (SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_REGS | SUSP_SH_SF) | ||
| 37 | /* | 38 | /* |
| 38 | * U-standby mode is unsupported since it needs bootloader hacks | 39 | * U-standby mode is unsupported since it needs bootloader hacks |
| 39 | */ | 40 | */ |
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) |
