mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-29 23:28:52 +01:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
7
arch/sh/kernel/cpu/shmobile/Makefile
Normal file
7
arch/sh/kernel/cpu/shmobile/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Makefile for the Linux/SuperH SH-Mobile backends.
|
||||
#
|
||||
|
||||
# Power Management & Sleep mode
|
||||
obj-$(CONFIG_PM) += pm.o sleep.o
|
||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
101
arch/sh/kernel/cpu/shmobile/cpuidle.c
Normal file
101
arch/sh/kernel/cpu/shmobile/cpuidle.c
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* arch/sh/kernel/cpu/shmobile/cpuidle.c
|
||||
*
|
||||
* Cpuidle support code for SuperH Mobile
|
||||
*
|
||||
* Copyright (C) 2009 Magnus Damm
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/export.h>
|
||||
#include <asm/suspend.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
static unsigned long cpuidle_mode[] = {
|
||||
SUSP_SH_SLEEP, /* regular sleep mode */
|
||||
SUSP_SH_SLEEP | SUSP_SH_SF, /* sleep mode + self refresh */
|
||||
SUSP_SH_STANDBY | SUSP_SH_SF, /* software standby mode + self refresh */
|
||||
};
|
||||
|
||||
static int cpuidle_sleep_enter(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv,
|
||||
int index)
|
||||
{
|
||||
unsigned long allowed_mode = SUSP_SH_SLEEP;
|
||||
int requested_state = index;
|
||||
int allowed_state;
|
||||
int k;
|
||||
|
||||
/* convert allowed mode to allowed state */
|
||||
for (k = ARRAY_SIZE(cpuidle_mode) - 1; k > 0; k--)
|
||||
if (cpuidle_mode[k] == allowed_mode)
|
||||
break;
|
||||
|
||||
allowed_state = k;
|
||||
|
||||
/* take the following into account for sleep mode selection:
|
||||
* - allowed_state: best mode allowed by hardware (clock deps)
|
||||
* - requested_state: best mode allowed by software (latencies)
|
||||
*/
|
||||
k = min_t(int, allowed_state, requested_state);
|
||||
|
||||
sh_mobile_call_standby(cpuidle_mode[k]);
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
static struct cpuidle_driver cpuidle_driver = {
|
||||
.name = "sh_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.states = {
|
||||
{
|
||||
.exit_latency = 1,
|
||||
.target_residency = 1 * 2,
|
||||
.power_usage = 3,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.enter = cpuidle_sleep_enter,
|
||||
.name = "C1",
|
||||
.desc = "SuperH Sleep Mode",
|
||||
},
|
||||
{
|
||||
.exit_latency = 100,
|
||||
.target_residency = 1 * 2,
|
||||
.power_usage = 1,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.enter = cpuidle_sleep_enter,
|
||||
.name = "C2",
|
||||
.desc = "SuperH Sleep Mode [SF]",
|
||||
.disabled = true,
|
||||
},
|
||||
{
|
||||
.exit_latency = 2300,
|
||||
.target_residency = 1 * 2,
|
||||
.power_usage = 1,
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,
|
||||
.enter = cpuidle_sleep_enter,
|
||||
.name = "C3",
|
||||
.desc = "SuperH Mobile Standby Mode [SF]",
|
||||
.disabled = true,
|
||||
},
|
||||
},
|
||||
.safe_state_index = 0,
|
||||
.state_count = 3,
|
||||
};
|
||||
|
||||
int __init sh_mobile_setup_cpuidle(void)
|
||||
{
|
||||
if (sh_mobile_sleep_supported & SUSP_SH_SF)
|
||||
cpuidle_driver.states[1].disabled = false;
|
||||
|
||||
if (sh_mobile_sleep_supported & SUSP_SH_STANDBY)
|
||||
cpuidle_driver.states[2].disabled = false;
|
||||
|
||||
return cpuidle_register(&cpuidle_driver, NULL);
|
||||
}
|
||||
156
arch/sh/kernel/cpu/shmobile/pm.c
Normal file
156
arch/sh/kernel/cpu/shmobile/pm.c
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* arch/sh/kernel/cpu/shmobile/pm.c
|
||||
*
|
||||
* Power management support code for SuperH Mobile
|
||||
*
|
||||
* Copyright (C) 2009 Magnus Damm
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <asm/suspend.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/bl_bit.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:
|
||||
*
|
||||
* Sleep mode is just plain "sleep" instruction
|
||||
* Sleep Self-Refresh mode is above plus RAM put in Self-Refresh
|
||||
* Standby Self-Refresh mode is above plus stopped clocks
|
||||
*/
|
||||
#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_SF \
|
||||
(SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_REGS | SUSP_SH_SF)
|
||||
/*
|
||||
* U-standby mode is unsupported since it needs bootloader hacks
|
||||
*/
|
||||
|
||||
#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 *)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, 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);
|
||||
local_irq_disable();
|
||||
clear_bl_bit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_suspend_ops sh_pm_ops = {
|
||||
.enter = sh_pm_enter,
|
||||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
|
||||
static int __init sh_pm_init(void)
|
||||
{
|
||||
suspend_set_ops(&sh_pm_ops);
|
||||
return sh_mobile_setup_cpuidle();
|
||||
}
|
||||
|
||||
late_initcall(sh_pm_init);
|
||||
405
arch/sh/kernel/cpu/shmobile/sleep.S
Normal file
405
arch/sh/kernel/cpu/shmobile/sleep.S
Normal file
|
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
* arch/sh/kernel/cpu/sh4a/sleep-sh_mobile.S
|
||||
*
|
||||
* Sleep mode and Standby modes support for SuperH Mobile
|
||||
*
|
||||
* Copyright (C) 2009 Magnus Damm
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/sys.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/suspend.h>
|
||||
|
||||
/*
|
||||
* Kernel mode register usage, see entry.S:
|
||||
* k0 scratch
|
||||
* k1 scratch
|
||||
*/
|
||||
#define k0 r0
|
||||
#define k1 r1
|
||||
|
||||
/* 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)
|
||||
|
||||
/* save mode flags */
|
||||
mov.l r4, @(SH_SLEEP_MODE, r5)
|
||||
|
||||
/* save original vbr */
|
||||
stc vbr, r0
|
||||
mov.l r0, @(SH_SLEEP_VBR, r5)
|
||||
|
||||
/* point vbr to our on-chip memory page */
|
||||
ldc r5, vbr
|
||||
|
||||
/* save return address */
|
||||
sts pr, r0
|
||||
mov.l r0, @(SH_SLEEP_SPC, r5)
|
||||
|
||||
/* save sr */
|
||||
stc sr, r0
|
||||
mov.l r0, @(SH_SLEEP_SR, r5)
|
||||
|
||||
/* save general purpose registers to stack if needed */
|
||||
mov.l @(SH_SLEEP_MODE, r5), r0
|
||||
tst #SUSP_SH_REGS, r0
|
||||
bt skip_regs_save
|
||||
|
||||
sts.l pr, @-r15
|
||||
mov.l r14, @-r15
|
||||
mov.l r13, @-r15
|
||||
mov.l r12, @-r15
|
||||
mov.l r11, @-r15
|
||||
mov.l r10, @-r15
|
||||
mov.l r9, @-r15
|
||||
mov.l r8, @-r15
|
||||
|
||||
/* make sure bank0 is selected, save low registers */
|
||||
mov.l rb_bit, r9
|
||||
not r9, r9
|
||||
bsr set_sr
|
||||
mov #0, r10
|
||||
|
||||
bsr save_low_regs
|
||||
nop
|
||||
|
||||
/* switch to bank 1, save low registers */
|
||||
mov.l rb_bit, r10
|
||||
bsr set_sr
|
||||
mov #-1, r9
|
||||
|
||||
bsr save_low_regs
|
||||
nop
|
||||
|
||||
/* switch back to bank 0 */
|
||||
mov.l rb_bit, r9
|
||||
not r9, r9
|
||||
bsr set_sr
|
||||
mov #0, r10
|
||||
|
||||
skip_regs_save:
|
||||
|
||||
/* save sp, also set to internal ram */
|
||||
mov.l r15, @(SH_SLEEP_SP, r5)
|
||||
mov r5, r15
|
||||
|
||||
/* 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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
/* set mode to "software standby mode" */
|
||||
bra do_sleep
|
||||
mov #0x80, r1
|
||||
|
||||
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
|
||||
|
||||
test_ustandby:
|
||||
tst #SUSP_SH_USTANDBY, r0
|
||||
bt force_sleep
|
||||
|
||||
/* set mode to "u-standby mode" */
|
||||
bra do_sleep
|
||||
mov #0x10, r1
|
||||
|
||||
force_sleep:
|
||||
|
||||
/* set mode to "sleep mode" */
|
||||
mov #0x00, r1
|
||||
|
||||
do_sleep:
|
||||
/* setup and enter selected standby mode */
|
||||
bsr get_register
|
||||
mov #SH_SLEEP_REG_STBCR, r0
|
||||
mov.l r1, @r0
|
||||
again:
|
||||
sleep
|
||||
bra again
|
||||
nop
|
||||
|
||||
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
|
||||
|
||||
set_sr:
|
||||
stc sr, r8
|
||||
and r9, r8
|
||||
or r10, r8
|
||||
ldc r8, sr
|
||||
rts
|
||||
nop
|
||||
|
||||
save_low_regs:
|
||||
mov.l r7, @-r15
|
||||
mov.l r6, @-r15
|
||||
mov.l r5, @-r15
|
||||
mov.l r4, @-r15
|
||||
mov.l r3, @-r15
|
||||
mov.l r2, @-r15
|
||||
mov.l r1, @-r15
|
||||
rts
|
||||
mov.l r0, @-r15
|
||||
|
||||
.balign 4
|
||||
rb_bit: .long 0x20000000 ! RB=1
|
||||
|
||||
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 @(SH_SLEEP_SPC, r5), r0
|
||||
ldc r0, spc
|
||||
|
||||
/* restore vbr */
|
||||
mov.l @(SH_SLEEP_VBR, r5), r0
|
||||
ldc r0, vbr
|
||||
|
||||
/* setup ssr with saved sr */
|
||||
mov.l @(SH_SLEEP_SR, r5), r0
|
||||
ldc r0, ssr
|
||||
|
||||
/* restore sp */
|
||||
mov.l @(SH_SLEEP_SP, r5), r15
|
||||
|
||||
/* restore sleep mode register */
|
||||
bsr restore_register
|
||||
mov #SH_SLEEP_REG_STBCR, r0
|
||||
|
||||
/* call self-refresh resume code if needed */
|
||||
mov.l @(SH_SLEEP_MODE, r5), r0
|
||||
tst #SUSP_SH_SF, r0
|
||||
bt skip_restore_sf
|
||||
|
||||
mov.l @(SH_SLEEP_SF_POST, r5), r0
|
||||
jsr @r0
|
||||
nop
|
||||
|
||||
skip_restore_sf:
|
||||
/* 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:
|
||||
|
||||
/* restore general purpose registers if needed */
|
||||
mov.l @(SH_SLEEP_MODE, r5), r0
|
||||
tst #SUSP_SH_REGS, r0
|
||||
bt skip_restore_regs
|
||||
|
||||
/* switch to bank 1, restore low registers */
|
||||
mov.l _rb_bit, r10
|
||||
bsr _set_sr
|
||||
mov #-1, r9
|
||||
|
||||
bsr restore_low_regs
|
||||
nop
|
||||
|
||||
/* switch to bank0, restore low registers */
|
||||
mov.l _rb_bit, r9
|
||||
not r9, r9
|
||||
bsr _set_sr
|
||||
mov #0, r10
|
||||
|
||||
bsr restore_low_regs
|
||||
nop
|
||||
|
||||
/* restore the rest of the registers */
|
||||
mov.l @r15+, r8
|
||||
mov.l @r15+, r9
|
||||
mov.l @r15+, r10
|
||||
mov.l @r15+, r11
|
||||
mov.l @r15+, r12
|
||||
mov.l @r15+, r13
|
||||
mov.l @r15+, r14
|
||||
lds.l @r15+, pr
|
||||
|
||||
skip_restore_regs:
|
||||
rte
|
||||
nop
|
||||
|
||||
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
|
||||
|
||||
_set_sr:
|
||||
stc sr, r8
|
||||
and r9, r8
|
||||
or r10, r8
|
||||
ldc r8, sr
|
||||
rts
|
||||
nop
|
||||
|
||||
restore_low_regs:
|
||||
mov.l @r15+, r0
|
||||
mov.l @r15+, r1
|
||||
mov.l @r15+, r2
|
||||
mov.l @r15+, r3
|
||||
mov.l @r15+, r4
|
||||
mov.l @r15+, r5
|
||||
mov.l @r15+, r6
|
||||
rts
|
||||
mov.l @r15+, r7
|
||||
|
||||
.balign 4
|
||||
_rb_bit: .long 0x20000000 ! RB=1
|
||||
1: .long ~0x7ff
|
||||
ENTRY(sh_mobile_sleep_resume_end)
|
||||
Loading…
Add table
Add a link
Reference in a new issue