diff options
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/asm-offsets.c | 10 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/pm.c | 15 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/sleep.S | 92 |
3 files changed, 117 insertions, 0 deletions
diff --git a/arch/sh/kernel/asm-offsets.c b/arch/sh/kernel/asm-offsets.c index 9bdeff962e1c..6026b0f849a1 100644 --- a/arch/sh/kernel/asm-offsets.c +++ b/arch/sh/kernel/asm-offsets.c | |||
@@ -44,5 +44,15 @@ int main(void) | |||
44 | DEFINE(SH_SLEEP_BASE_ADDR, offsetof(struct sh_sleep_data, addr)); | 44 | DEFINE(SH_SLEEP_BASE_ADDR, offsetof(struct sh_sleep_data, addr)); |
45 | DEFINE(SH_SLEEP_BASE_DATA, offsetof(struct sh_sleep_data, data)); | 45 | DEFINE(SH_SLEEP_BASE_DATA, offsetof(struct sh_sleep_data, data)); |
46 | DEFINE(SH_SLEEP_REG_STBCR, offsetof(struct sh_sleep_regs, stbcr)); | 46 | DEFINE(SH_SLEEP_REG_STBCR, offsetof(struct sh_sleep_regs, stbcr)); |
47 | DEFINE(SH_SLEEP_REG_PTEH, offsetof(struct sh_sleep_regs, pteh)); | ||
48 | DEFINE(SH_SLEEP_REG_PTEL, offsetof(struct sh_sleep_regs, ptel)); | ||
49 | DEFINE(SH_SLEEP_REG_TTB, offsetof(struct sh_sleep_regs, ttb)); | ||
50 | DEFINE(SH_SLEEP_REG_TEA, offsetof(struct sh_sleep_regs, tea)); | ||
51 | DEFINE(SH_SLEEP_REG_MMUCR, offsetof(struct sh_sleep_regs, mmucr)); | ||
52 | DEFINE(SH_SLEEP_REG_PTEA, offsetof(struct sh_sleep_regs, ptea)); | ||
53 | DEFINE(SH_SLEEP_REG_PASCR, offsetof(struct sh_sleep_regs, pascr)); | ||
54 | DEFINE(SH_SLEEP_REG_IRMCR, offsetof(struct sh_sleep_regs, irmcr)); | ||
55 | DEFINE(SH_SLEEP_REG_CCR, offsetof(struct sh_sleep_regs, ccr)); | ||
56 | DEFINE(SH_SLEEP_REG_RAMCR, offsetof(struct sh_sleep_regs, ramcr)); | ||
47 | return 0; | 57 | return 0; |
48 | } | 58 | } |
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c index a94dc480f0c1..ca642f39e2e3 100644 --- a/arch/sh/kernel/cpu/shmobile/pm.c +++ b/arch/sh/kernel/cpu/shmobile/pm.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/suspend.h> | 15 | #include <linux/suspend.h> |
16 | #include <asm/suspend.h> | 16 | #include <asm/suspend.h> |
17 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
18 | #include <asm/cacheflush.h> | ||
18 | 19 | ||
19 | /* | 20 | /* |
20 | * Notifier lists for pre/post sleep notification | 21 | * Notifier lists for pre/post sleep notification |
@@ -54,6 +55,10 @@ void sh_mobile_call_standby(unsigned long mode) | |||
54 | atomic_notifier_call_chain(&sh_mobile_pre_sleep_notifier_list, | 55 | atomic_notifier_call_chain(&sh_mobile_pre_sleep_notifier_list, |
55 | mode, NULL); | 56 | mode, NULL); |
56 | 57 | ||
58 | /* flush the caches if MMU flag is set */ | ||
59 | if (mode & SUSP_SH_MMU) | ||
60 | flush_cache_all(); | ||
61 | |||
57 | /* Let assembly snippet in on-chip memory handle the rest */ | 62 | /* Let assembly snippet in on-chip memory handle the rest */ |
58 | standby_onchip_mem(mode, ILRAM_BASE); | 63 | standby_onchip_mem(mode, ILRAM_BASE); |
59 | 64 | ||
@@ -81,6 +86,16 @@ void sh_mobile_register_self_refresh(unsigned long flags, | |||
81 | /* part 0: data area */ | 86 | /* part 0: data area */ |
82 | sdp = onchip_mem; | 87 | sdp = onchip_mem; |
83 | sdp->addr.stbcr = 0xa4150020; /* STBCR */ | 88 | sdp->addr.stbcr = 0xa4150020; /* STBCR */ |
89 | sdp->addr.pteh = 0xff000000; /* PTEH */ | ||
90 | sdp->addr.ptel = 0xff000004; /* PTEL */ | ||
91 | sdp->addr.ttb = 0xff000008; /* TTB */ | ||
92 | sdp->addr.tea = 0xff00000c; /* TEA */ | ||
93 | sdp->addr.mmucr = 0xff000010; /* MMUCR */ | ||
94 | sdp->addr.ptea = 0xff000034; /* PTEA */ | ||
95 | sdp->addr.pascr = 0xff000070; /* PASCR */ | ||
96 | sdp->addr.irmcr = 0xff000078; /* IRMCR */ | ||
97 | sdp->addr.ccr = 0xff00001c; /* CCR */ | ||
98 | sdp->addr.ramcr = 0xff000074; /* RAMCR */ | ||
84 | vp = sdp + 1; | 99 | vp = sdp + 1; |
85 | 100 | ||
86 | /* part 1: common code to enter sleep mode */ | 101 | /* part 1: common code to enter sleep mode */ |
diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S index d3221d9b88be..e620bf397af5 100644 --- a/arch/sh/kernel/cpu/shmobile/sleep.S +++ b/arch/sh/kernel/cpu/shmobile/sleep.S | |||
@@ -52,6 +52,57 @@ ENTRY(sh_mobile_sleep_enter_start) | |||
52 | bsr save_register | 52 | bsr save_register |
53 | mov #SH_SLEEP_REG_STBCR, r0 | 53 | mov #SH_SLEEP_REG_STBCR, r0 |
54 | 54 | ||
55 | /* save mmu and cache context if needed */ | ||
56 | mov.l @(SH_SLEEP_MODE, r5), r0 | ||
57 | tst #SUSP_SH_MMU, r0 | ||
58 | bt skip_mmu_save_disable | ||
59 | |||
60 | /* save mmu state */ | ||
61 | bsr save_register | ||
62 | mov #SH_SLEEP_REG_PTEH, r0 | ||
63 | |||
64 | bsr save_register | ||
65 | mov #SH_SLEEP_REG_PTEL, r0 | ||
66 | |||
67 | bsr save_register | ||
68 | mov #SH_SLEEP_REG_TTB, r0 | ||
69 | |||
70 | bsr save_register | ||
71 | mov #SH_SLEEP_REG_TEA, r0 | ||
72 | |||
73 | bsr save_register | ||
74 | mov #SH_SLEEP_REG_MMUCR, r0 | ||
75 | |||
76 | bsr save_register | ||
77 | mov #SH_SLEEP_REG_PTEA, r0 | ||
78 | |||
79 | bsr save_register | ||
80 | mov #SH_SLEEP_REG_PASCR, r0 | ||
81 | |||
82 | bsr save_register | ||
83 | mov #SH_SLEEP_REG_IRMCR, r0 | ||
84 | |||
85 | /* invalidate TLBs and disable the MMU */ | ||
86 | bsr get_register | ||
87 | mov #SH_SLEEP_REG_MMUCR, r0 | ||
88 | mov #4, r1 | ||
89 | mov.l r1, @r0 | ||
90 | icbi @r0 | ||
91 | |||
92 | /* save cache registers and disable caches */ | ||
93 | bsr save_register | ||
94 | mov #SH_SLEEP_REG_CCR, r0 | ||
95 | |||
96 | bsr save_register | ||
97 | mov #SH_SLEEP_REG_RAMCR, r0 | ||
98 | |||
99 | bsr get_register | ||
100 | mov #SH_SLEEP_REG_CCR, r0 | ||
101 | mov #0, r1 | ||
102 | mov.l r1, @r0 | ||
103 | icbi @r0 | ||
104 | |||
105 | skip_mmu_save_disable: | ||
55 | /* call self-refresh entering code if needed */ | 106 | /* call self-refresh entering code if needed */ |
56 | mov.l @(SH_SLEEP_MODE, r5), r0 | 107 | mov.l @(SH_SLEEP_MODE, r5), r0 |
57 | tst #SUSP_SH_SF, r0 | 108 | tst #SUSP_SH_SF, r0 |
@@ -166,6 +217,47 @@ ENTRY(sh_mobile_sleep_resume_start) | |||
166 | nop | 217 | nop |
167 | 218 | ||
168 | skip_restore_sf: | 219 | skip_restore_sf: |
220 | /* restore mmu and cache state if needed */ | ||
221 | mov.l @(SH_SLEEP_MODE, r5), r0 | ||
222 | tst #SUSP_SH_MMU, r0 | ||
223 | bt skip_restore_mmu | ||
224 | |||
225 | /* restore mmu state */ | ||
226 | bsr restore_register | ||
227 | mov #SH_SLEEP_REG_PTEH, r0 | ||
228 | |||
229 | bsr restore_register | ||
230 | mov #SH_SLEEP_REG_PTEL, r0 | ||
231 | |||
232 | bsr restore_register | ||
233 | mov #SH_SLEEP_REG_TTB, r0 | ||
234 | |||
235 | bsr restore_register | ||
236 | mov #SH_SLEEP_REG_TEA, r0 | ||
237 | |||
238 | bsr restore_register | ||
239 | mov #SH_SLEEP_REG_PTEA, r0 | ||
240 | |||
241 | bsr restore_register | ||
242 | mov #SH_SLEEP_REG_PASCR, r0 | ||
243 | |||
244 | bsr restore_register | ||
245 | mov #SH_SLEEP_REG_IRMCR, r0 | ||
246 | |||
247 | bsr restore_register | ||
248 | mov #SH_SLEEP_REG_MMUCR, r0 | ||
249 | icbi @r0 | ||
250 | |||
251 | /* restore cache settings */ | ||
252 | bsr restore_register | ||
253 | mov #SH_SLEEP_REG_RAMCR, r0 | ||
254 | icbi @r0 | ||
255 | |||
256 | bsr restore_register | ||
257 | mov #SH_SLEEP_REG_CCR, r0 | ||
258 | icbi @r0 | ||
259 | |||
260 | skip_restore_mmu: | ||
169 | rte | 261 | rte |
170 | nop | 262 | nop |
171 | 263 | ||