diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 19:03:16 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 19:03:16 -0800 |
commit | 3a43aaa31790c36b69ebf8a6396f37fade86b531 (patch) | |
tree | 7c7f8da6219d546f2b44534cb7be1fb5591d6ac4 /arch/sh/kernel/cpu/shmobile | |
parent | aed886ce777590eac87f7ce2897d9f8357754331 (diff) | |
parent | 6a5a0b9139b19dd1a107870269a35bc9cf18d2dc (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (137 commits)
sh: include empty zero page in romImage
sh: Make associative cache writes fatal on all SH-4A parts.
sh: Drop associative writes for SH-4 cache flushes.
sh: Partial revert of copy/clear_user_highpage() optimizations.
sh: Add default uImage rule for se7724, ap325rxa, and migor.
sh: allow runtime pm without suspend/resume callbacks
sh: mach-ecovec24: Remove un-defined settings for VPU
sh: mach-ecovec24: LCDC drive ability become high
sh: fix sh7724 VEU3F resource size
serial: sh-sci: Fix too early port disabling.
sh: pfc: pr_info() -> pr_debug() cleanups.
sh: pfc: Convert from ctrl_xxx() to __raw_xxx() I/O routines.
sh: Improve kfr2r09 serial port setup code
sh: Break out SuperH PFC code
sh: Move KEYSC header file
sh: convert /proc/cpu/aligmnent, /proc/cpu/kernel_alignment to seq_file
sh: Add CPG save/restore code for sh7724 R-standby
sh: Add SDHI power control support to Ecovec
mfd: Add power control platform data to SDHI driver
sh: mach-ecovec24: modify address map
...
Diffstat (limited to 'arch/sh/kernel/cpu/shmobile')
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/cpuidle.c | 42 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/pm.c | 117 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/pm_runtime.c | 17 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/shmobile/sleep.S | 344 |
4 files changed, 324 insertions, 196 deletions
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c index 1c504bd972c..83972aa319c 100644 --- a/arch/sh/kernel/cpu/shmobile/cpuidle.c +++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c @@ -87,25 +87,31 @@ void sh_mobile_setup_cpuidle(void) dev->safe_state = state; - state = &dev->states[i++]; - snprintf(state->name, CPUIDLE_NAME_LEN, "C1"); - strncpy(state->desc, "SuperH Sleep Mode [SF]", CPUIDLE_DESC_LEN); - state->exit_latency = 100; - state->target_residency = 1 * 2; - state->power_usage = 1; - state->flags = 0; - state->flags |= CPUIDLE_FLAG_TIME_VALID; - state->enter = cpuidle_sleep_enter; + if (sh_mobile_sleep_supported & SUSP_SH_SF) { + state = &dev->states[i++]; + snprintf(state->name, CPUIDLE_NAME_LEN, "C1"); + strncpy(state->desc, "SuperH Sleep Mode [SF]", + CPUIDLE_DESC_LEN); + state->exit_latency = 100; + state->target_residency = 1 * 2; + state->power_usage = 1; + state->flags = 0; + state->flags |= CPUIDLE_FLAG_TIME_VALID; + state->enter = cpuidle_sleep_enter; + } - state = &dev->states[i++]; - snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); - strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", CPUIDLE_DESC_LEN); - state->exit_latency = 2300; - state->target_residency = 1 * 2; - state->power_usage = 1; - state->flags = 0; - state->flags |= CPUIDLE_FLAG_TIME_VALID; - state->enter = cpuidle_sleep_enter; + if (sh_mobile_sleep_supported & SUSP_SH_STANDBY) { + state = &dev->states[i++]; + snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); + strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", + CPUIDLE_DESC_LEN); + state->exit_latency = 2300; + state->target_residency = 1 * 2; + state->power_usage = 1; + state->flags = 0; + state->flags |= CPUIDLE_FLAG_TIME_VALID; + state->enter = cpuidle_sleep_enter; + } dev->state_count = i; diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c index ee3c2aaf66f..ca029a44743 100644 --- a/arch/sh/kernel/cpu/shmobile/pm.c +++ b/arch/sh/kernel/cpu/shmobile/pm.c @@ -15,6 +15,13 @@ #include <linux/suspend.h> #include <asm/suspend.h> #include <asm/uaccess.h> +#include <asm/cacheflush.h> + +/* + * Notifier lists for pre/post sleep notification + */ +ATOMIC_NOTIFIER_HEAD(sh_mobile_pre_sleep_notifier_list); +ATOMIC_NOTIFIER_HEAD(sh_mobile_post_sleep_notifier_list); /* * Sleep modes available on SuperH Mobile: @@ -26,30 +33,105 @@ #define SUSP_MODE_SLEEP (SUSP_SH_SLEEP) #define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF) #define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF) +#define SUSP_MODE_RSTANDBY (SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_SF) + /* + * U-standby mode is unsupported since it needs bootloader hacks + */ -/* - * The following modes are not there yet: - * - * R-standby mode is unsupported, but will be added in the future - * U-standby mode is low priority since it needs bootloader hacks - */ - -#define ILRAM_BASE 0xe5200000 - -extern const unsigned char sh_mobile_standby[]; -extern const unsigned int sh_mobile_standby_size; +#ifdef CONFIG_CPU_SUBTYPE_SH7724 +#define RAM_BASE 0xfd800000 /* RSMEM */ +#else +#define RAM_BASE 0xe5200000 /* ILRAM */ +#endif void sh_mobile_call_standby(unsigned long mode) { - void *onchip_mem = (void *)ILRAM_BASE; - void (*standby_onchip_mem)(unsigned long, unsigned long) = onchip_mem; + void *onchip_mem = (void *)RAM_BASE; + struct sh_sleep_data *sdp = onchip_mem; + void (*standby_onchip_mem)(unsigned long, unsigned long); + + /* code located directly after data structure */ + standby_onchip_mem = (void *)(sdp + 1); + + atomic_notifier_call_chain(&sh_mobile_pre_sleep_notifier_list, + mode, NULL); + + /* flush the caches if MMU flag is set */ + if (mode & SUSP_SH_MMU) + flush_cache_all(); /* Let assembly snippet in on-chip memory handle the rest */ - standby_onchip_mem(mode, ILRAM_BASE); + standby_onchip_mem(mode, RAM_BASE); + + atomic_notifier_call_chain(&sh_mobile_post_sleep_notifier_list, + mode, NULL); +} + +extern char sh_mobile_sleep_enter_start; +extern char sh_mobile_sleep_enter_end; + +extern char sh_mobile_sleep_resume_start; +extern char sh_mobile_sleep_resume_end; + +unsigned long sh_mobile_sleep_supported = SUSP_SH_SLEEP; + +void sh_mobile_register_self_refresh(unsigned long flags, + void *pre_start, void *pre_end, + void *post_start, void *post_end) +{ + void *onchip_mem = (void *)RAM_BASE; + void *vp; + struct sh_sleep_data *sdp; + int n; + + /* part 0: data area */ + sdp = onchip_mem; + sdp->addr.stbcr = 0xa4150020; /* STBCR */ + sdp->addr.bar = 0xa4150040; /* BAR */ + sdp->addr.pteh = 0xff000000; /* PTEH */ + sdp->addr.ptel = 0xff000004; /* PTEL */ + sdp->addr.ttb = 0xff000008; /* TTB */ + sdp->addr.tea = 0xff00000c; /* TEA */ + sdp->addr.mmucr = 0xff000010; /* MMUCR */ + sdp->addr.ptea = 0xff000034; /* PTEA */ + sdp->addr.pascr = 0xff000070; /* PASCR */ + sdp->addr.irmcr = 0xff000078; /* IRMCR */ + sdp->addr.ccr = 0xff00001c; /* CCR */ + sdp->addr.ramcr = 0xff000074; /* RAMCR */ + vp = sdp + 1; + + /* part 1: common code to enter sleep mode */ + n = &sh_mobile_sleep_enter_end - &sh_mobile_sleep_enter_start; + memcpy(vp, &sh_mobile_sleep_enter_start, n); + vp += roundup(n, 4); + + /* part 2: board specific code to enter self-refresh mode */ + n = pre_end - pre_start; + memcpy(vp, pre_start, n); + sdp->sf_pre = (unsigned long)vp; + vp += roundup(n, 4); + + /* part 3: board specific code to resume from self-refresh mode */ + n = post_end - post_start; + memcpy(vp, post_start, n); + sdp->sf_post = (unsigned long)vp; + vp += roundup(n, 4); + + /* part 4: common code to resume from sleep mode */ + WARN_ON(vp > (onchip_mem + 0x600)); + vp = onchip_mem + 0x600; /* located at interrupt vector */ + n = &sh_mobile_sleep_resume_end - &sh_mobile_sleep_resume_start; + memcpy(vp, &sh_mobile_sleep_resume_start, n); + sdp->resume = (unsigned long)vp; + + sh_mobile_sleep_supported |= flags; } static int sh_pm_enter(suspend_state_t state) { + if (!(sh_mobile_sleep_supported & SUSP_MODE_STANDBY_SF)) + return -ENXIO; + local_irq_disable(); set_bl_bit(); sh_mobile_call_standby(SUSP_MODE_STANDBY_SF); @@ -65,13 +147,6 @@ static struct platform_suspend_ops sh_pm_ops = { static int __init sh_pm_init(void) { - void *onchip_mem = (void *)ILRAM_BASE; - - /* Copy the assembly snippet to the otherwise ununsed ILRAM */ - memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size); - wmb(); - ctrl_barrier(); - suspend_set_ops(&sh_pm_ops); sh_mobile_setup_cpuidle(); return 0; diff --git a/arch/sh/kernel/cpu/shmobile/pm_runtime.c b/arch/sh/kernel/cpu/shmobile/pm_runtime.c index 7c615b17e20..6dcb8166a64 100644 --- a/arch/sh/kernel/cpu/shmobile/pm_runtime.c +++ b/arch/sh/kernel/cpu/shmobile/pm_runtime.c @@ -45,12 +45,14 @@ static int __platform_pm_runtime_resume(struct platform_device *pdev) dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk); - if (d->driver && d->driver->pm && d->driver->pm->runtime_resume) { + if (d->driver) { hwblk_enable(hwblk_info, hwblk); ret = 0; if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) { - ret = d->driver->pm->runtime_resume(d); + if (d->driver->pm && d->driver->pm->runtime_resume) + ret = d->driver->pm->runtime_resume(d); + if (!ret) clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags); else @@ -73,12 +75,15 @@ static int __platform_pm_runtime_suspend(struct platform_device *pdev) dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk); - if (d->driver && d->driver->pm && d->driver->pm->runtime_suspend) { + if (d->driver) { BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags)); + ret = 0; - hwblk_enable(hwblk_info, hwblk); - ret = d->driver->pm->runtime_suspend(d); - hwblk_disable(hwblk_info, hwblk); + if (d->driver->pm && d->driver->pm->runtime_suspend) { + hwblk_enable(hwblk_info, hwblk); + ret = d->driver->pm->runtime_suspend(d); + hwblk_disable(hwblk_info, hwblk); + } if (!ret) { set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags); diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S index a439e6c7824..e9dd7fa0abd 100644 --- a/arch/sh/kernel/cpu/shmobile/sleep.S +++ b/arch/sh/kernel/cpu/shmobile/sleep.S @@ -20,79 +20,103 @@ * Kernel mode register usage, see entry.S: * k0 scratch * k1 scratch - * k4 scratch */ #define k0 r0 #define k1 r1 -#define k4 r4 -/* manage self-refresh and enter standby mode. +/* manage self-refresh and enter standby mode. must be self-contained. * this code will be copied to on-chip memory and executed from there. */ + .balign 4 +ENTRY(sh_mobile_sleep_enter_start) - .balign 4096,0,4096 -ENTRY(sh_mobile_standby) + /* save mode flags */ + mov.l r4, @(SH_SLEEP_MODE, r5) /* save original vbr */ - stc vbr, r1 - mova saved_vbr, r0 - mov.l r1, @r0 + stc vbr, r0 + mov.l r0, @(SH_SLEEP_VBR, r5) /* point vbr to our on-chip memory page */ ldc r5, vbr /* save return address */ - mova saved_spc, r0 - sts pr, r5 - mov.l r5, @r0 + sts pr, r0 + mov.l r0, @(SH_SLEEP_SPC, r5) /* save sr */ - mova saved_sr, r0 - stc sr, r5 - mov.l r5, @r0 + stc sr, r0 + mov.l r0, @(SH_SLEEP_SR, r5) - /* save mode flags */ - mova saved_mode, r0 - mov.l r4, @r0 + /* save sp */ + mov.l r15, @(SH_SLEEP_SP, r5) + + /* save stbcr */ + bsr save_register + mov #SH_SLEEP_REG_STBCR, r0 + + /* save mmu and cache context if needed */ + mov.l @(SH_SLEEP_MODE, r5), r0 + tst #SUSP_SH_MMU, r0 + bt skip_mmu_save_disable + + /* save mmu state */ + bsr save_register + mov #SH_SLEEP_REG_PTEH, r0 + + bsr save_register + mov #SH_SLEEP_REG_PTEL, r0 + + bsr save_register + mov #SH_SLEEP_REG_TTB, r0 + + bsr save_register + mov #SH_SLEEP_REG_TEA, r0 + + bsr save_register + mov #SH_SLEEP_REG_MMUCR, r0 + + bsr save_register + mov #SH_SLEEP_REG_PTEA, r0 + + bsr save_register + mov #SH_SLEEP_REG_PASCR, r0 - /* put mode flags in r0 */ - mov r4, r0 + bsr save_register + mov #SH_SLEEP_REG_IRMCR, r0 + /* invalidate TLBs and disable the MMU */ + bsr get_register + mov #SH_SLEEP_REG_MMUCR, r0 + mov #4, r1 + mov.l r1, @r0 + icbi @r0 + + /* save cache registers and disable caches */ + bsr save_register + mov #SH_SLEEP_REG_CCR, r0 + + bsr save_register + mov #SH_SLEEP_REG_RAMCR, r0 + + bsr get_register + mov #SH_SLEEP_REG_CCR, r0 + mov #0, r1 + mov.l r1, @r0 + icbi @r0 + +skip_mmu_save_disable: + /* call self-refresh entering code if needed */ + mov.l @(SH_SLEEP_MODE, r5), r0 tst #SUSP_SH_SF, r0 bt skip_set_sf -#ifdef CONFIG_CPU_SUBTYPE_SH7724 - /* DBSC: put memory in self-refresh mode */ - mov.l dben_reg, r4 - mov.l dben_data0, r1 - mov.l r1, @r4 - - mov.l dbrfpdn0_reg, r4 - mov.l dbrfpdn0_data0, r1 - mov.l r1, @r4 - - mov.l dbcmdcnt_reg, r4 - mov.l dbcmdcnt_data0, r1 - mov.l r1, @r4 - - mov.l dbcmdcnt_reg, r4 - mov.l dbcmdcnt_data1, r1 - mov.l r1, @r4 - - mov.l dbrfpdn0_reg, r4 - mov.l dbrfpdn0_data1, r1 - mov.l r1, @r4 -#else - /* SBSC: disable power down and put in self-refresh mode */ - mov.l 1f, r4 - mov.l 2f, r1 - mov.l @r4, r2 - or r1, r2 - mov.l 3f, r3 - and r3, r2 - mov.l r2, @r4 -#endif + + mov.l @(SH_SLEEP_SF_PRE, r5), r0 + jsr @r0 + nop skip_set_sf: + mov.l @(SH_SLEEP_MODE, r5), r0 tst #SUSP_SH_STANDBY, r0 bt test_rstandby @@ -104,6 +128,12 @@ test_rstandby: tst #SUSP_SH_RSTANDBY, r0 bt test_ustandby + /* setup BAR register */ + bsr get_register + mov #SH_SLEEP_REG_BAR, r0 + mov.l @(SH_SLEEP_RESUME, r5), r1 + mov.l r1, @r0 + /* set mode to "r-standby mode" */ bra do_sleep mov #0x20, r1 @@ -123,124 +153,136 @@ force_sleep: do_sleep: /* setup and enter selected standby mode */ - mov.l 5f, r4 - mov.l r1, @r4 + bsr get_register + mov #SH_SLEEP_REG_STBCR, r0 + mov.l r1, @r0 again: sleep bra again nop -restore_jump_vbr: +save_register: + add #SH_SLEEP_BASE_ADDR, r0 + mov.l @(r0, r5), r1 + add #-SH_SLEEP_BASE_ADDR, r0 + mov.l @r1, r1 + add #SH_SLEEP_BASE_DATA, r0 + mov.l r1, @(r0, r5) + add #-SH_SLEEP_BASE_DATA, r0 + rts + nop + +get_register: + add #SH_SLEEP_BASE_ADDR, r0 + mov.l @(r0, r5), r0 + rts + nop +ENTRY(sh_mobile_sleep_enter_end) + + .balign 4 +ENTRY(sh_mobile_sleep_resume_start) + + /* figure out start address */ + bsr 0f + nop +0: + sts pr, k1 + mov.l 1f, k0 + and k0, k1 + + /* store pointer to data area in VBR */ + ldc k1, vbr + + /* setup sr with saved sr */ + mov.l @(SH_SLEEP_SR, k1), k0 + ldc k0, sr + + /* now: user register set! */ + stc vbr, r5 + /* setup spc with return address to c code */ - mov.l saved_spc, k0 - ldc k0, spc + mov.l @(SH_SLEEP_SPC, r5), r0 + ldc r0, spc /* restore vbr */ - mov.l saved_vbr, k0 - ldc k0, vbr + mov.l @(SH_SLEEP_VBR, r5), r0 + ldc r0, vbr /* setup ssr with saved sr */ - mov.l saved_sr, k0 - ldc k0, ssr + mov.l @(SH_SLEEP_SR, r5), r0 + ldc r0, ssr - /* get mode flags */ - mov.l saved_mode, k0 + /* restore sp */ + mov.l @(SH_SLEEP_SP, r5), r15 -done_sleep: - /* reset standby mode to sleep mode */ - mov.l 5f, k4 - mov #0x00, k1 - mov.l k1, @k4 + /* restore sleep mode register */ + bsr restore_register + mov #SH_SLEEP_REG_STBCR, r0 - tst #SUSP_SH_SF, k0 + /* call self-refresh resume code if needed */ + mov.l @(SH_SLEEP_MODE, r5), r0 + tst #SUSP_SH_SF, r0 bt skip_restore_sf -#ifdef CONFIG_CPU_SUBTYPE_SH7724 - /* DBSC: put memory in auto-refresh mode */ - mov.l dbrfpdn0_reg, k4 - mov.l dbrfpdn0_data0, k1 - mov.l k1, @k4 - - nop /* sleep 140 ns */ - nop - nop - nop - - mov.l dbcmdcnt_reg, k4 - mov.l dbcmdcnt_data0, k1 - mov.l k1, @k4 - - mov.l dbcmdcnt_reg, k4 - mov.l dbcmdcnt_data1, k1 - mov.l k1, @k4 - - mov.l dben_reg, k4 - mov.l dben_data1, k1 - mov.l k1, @k4 - - mov.l dbrfpdn0_reg, k4 - mov.l dbrfpdn0_data2, k1 - mov.l k1, @k4 -#else - /* SBSC: set auto-refresh mode */ - mov.l 1f, k4 - mov.l @k4, k0 - mov.l 4f, k1 - and k1, k0 - mov.l k0, @k4 - mov.l 6f, k4 - mov.l 8f, k0 - mov.l @k4, k1 - mov #-1, k4 - add k4, k1 - or k1, k0 - mov.l 7f, k1 - mov.l k0, @k1 -#endif + mov.l @(SH_SLEEP_SF_POST, r5), r0 + jsr @r0 + nop + skip_restore_sf: - /* jump to vbr vector */ - mov.l saved_vbr, k0 - mov.l offset_vbr, k4 - add k4, k0 - jmp @k0 + /* restore mmu and cache state if needed */ + mov.l @(SH_SLEEP_MODE, r5), r0 + tst #SUSP_SH_MMU, r0 + bt skip_restore_mmu + + /* restore mmu state */ + bsr restore_register + mov #SH_SLEEP_REG_PTEH, r0 + + bsr restore_register + mov #SH_SLEEP_REG_PTEL, r0 + + bsr restore_register + mov #SH_SLEEP_REG_TTB, r0 + + bsr restore_register + mov #SH_SLEEP_REG_TEA, r0 + + bsr restore_register + mov #SH_SLEEP_REG_PTEA, r0 + + bsr restore_register + mov #SH_SLEEP_REG_PASCR, r0 + + bsr restore_register + mov #SH_SLEEP_REG_IRMCR, r0 + + bsr restore_register + mov #SH_SLEEP_REG_MMUCR, r0 + icbi @r0 + + /* restore cache settings */ + bsr restore_register + mov #SH_SLEEP_REG_RAMCR, r0 + icbi @r0 + + bsr restore_register + mov #SH_SLEEP_REG_CCR, r0 + icbi @r0 + +skip_restore_mmu: + rte nop - .balign 4 -saved_mode: .long 0 -saved_spc: .long 0 -saved_sr: .long 0 -saved_vbr: .long 0 -offset_vbr: .long 0x600 -#ifdef CONFIG_CPU_SUBTYPE_SH7724 -dben_reg: .long 0xfd000010 /* DBEN */ -dben_data0: .long 0 -dben_data1: .long 1 -dbrfpdn0_reg: .long 0xfd000040 /* DBRFPDN0 */ -dbrfpdn0_data0: .long 0 -dbrfpdn0_data1: .long 1 -dbrfpdn0_data2: .long 0x00010000 -dbcmdcnt_reg: .long 0xfd000014 /* DBCMDCNT */ -dbcmdcnt_data0: .long 2 -dbcmdcnt_data1: .long 4 -#else -1: .long 0xfe400008 /* SDCR0 */ -2: .long 0x00000400 -3: .long 0xffff7fff -4: .long 0xfffffbff -#endif -5: .long 0xa4150020 /* STBCR */ -6: .long 0xfe40001c /* RTCOR */ -7: .long 0xfe400018 /* RTCNT */ -8: .long 0xa55a0000 - - -/* interrupt vector @ 0x600 */ - .balign 0x400,0,0x400 - .long 0xdeadbeef - .balign 0x200,0,0x200 - bra restore_jump_vbr +restore_register: + add #SH_SLEEP_BASE_DATA, r0 + mov.l @(r0, r5), r1 + add #-SH_SLEEP_BASE_DATA, r0 + add #SH_SLEEP_BASE_ADDR, r0 + mov.l @(r0, r5), r0 + mov.l r1, @r0 + rts nop -sh_mobile_standby_end: -ENTRY(sh_mobile_standby_size) - .long sh_mobile_standby_end - sh_mobile_standby + .balign 4 +1: .long ~0x7ff +ENTRY(sh_mobile_sleep_resume_end) |