diff options
author | Chenhui Zhao <chenhui.zhao@freescale.com> | 2015-03-25 03:37:21 (GMT) |
---|---|---|
committer | Honghua Yin <Hong-Hua.Yin@freescale.com> | 2015-03-25 08:22:22 (GMT) |
commit | 9841cd09d8b0226792dd20bb82926413fa53e37f (patch) | |
tree | fb747993d92938ef7bd874f8f4151db15a6c845d /arch | |
parent | ce7468ae28590b496f78cb2678a289097f0c1804 (diff) | |
download | linux-fsl-qoriq-9841cd09d8b0226792dd20bb82926413fa53e37f.tar.xz |
powerpc: pm: save/restore CR register when doing deep sleep
Save and restore CR (Condition Register) register when doing deep sleep.
Otherwise, conditional statement will get wrong result after resuming from
deep sleep.
Free memory which is allocated in suspend code.
Change-Id: Ibe50138e85c164d0218a01f0f481bf484a02a45a
Signed-off-by: Chenhui Zhao <chenhui.zhao@freescale.com>
Reviewed-on: http://git.am.freescale.net:8181/33411
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Zhuoyu Zhang <Zhuoyu.Zhang@freescale.com>
Reviewed-by: Honghua Yin <Hong-Hua.Yin@freescale.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/85xx/deepsleep.c | 22 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/sleep.S | 6 |
2 files changed, 22 insertions, 6 deletions
diff --git a/arch/powerpc/platforms/85xx/deepsleep.c b/arch/powerpc/platforms/85xx/deepsleep.c index 454c070..755be0b 100644 --- a/arch/powerpc/platforms/85xx/deepsleep.c +++ b/arch/powerpc/platforms/85xx/deepsleep.c @@ -83,6 +83,11 @@ int fsl_dp_iomap(void) int ret = 0; phys_addr_t ccsr_phy_addr, dcsr_phy_addr; + saved_law = NULL; + ccsr_base = NULL; + dcsr_base = NULL; + pld_base = NULL; + ccsr_phy_addr = get_immrbase(); if (ccsr_phy_addr == -1) { pr_err("%s: Can't get the address of CCSR\n", __func__); @@ -128,31 +133,33 @@ int fsl_dp_iomap(void) if (!np) { pr_err("%s: Can't find the node of \"law\"\n", __func__); ret = -EINVAL; - goto pld_err; + goto alloc_err; } ret = of_property_read_u32(np, "fsl,num-laws", &num_laws); if (ret) { ret = -EINVAL; - goto pld_err; + goto alloc_err; } saved_law = kzalloc(sizeof(*saved_law) * num_laws, GFP_KERNEL); if (!saved_law) { ret = -ENOMEM; - goto pld_err; + goto alloc_err; } of_node_put(np); return 0; +alloc_err: + iounmap(pld_base); + pld_base = NULL; pld_err: iounmap(dcsr_base); + dcsr_base = NULL; dcsr_err: iounmap(ccsr_base); -ccsr_err: ccsr_base = NULL; - dcsr_base = NULL; - pld_base = NULL; +ccsr_err: return ret; } @@ -172,6 +179,9 @@ void fsl_dp_iounmap(void) iounmap(pld_base); pld_base = NULL; } + + kfree(saved_law); + saved_law = NULL; } static void fsl_dp_ddr_save(void *ccsr_base) diff --git a/arch/powerpc/platforms/85xx/sleep.S b/arch/powerpc/platforms/85xx/sleep.S index 9c7c0f3..a6e89b7 100644 --- a/arch/powerpc/platforms/85xx/sleep.S +++ b/arch/powerpc/platforms/85xx/sleep.S @@ -892,6 +892,8 @@ deepsleep_start: PPC_STL r8, 8(r9) mfspr r8, SPRN_TCR PPC_STL r8, 16(r9) + mfcr r8 + PPC_STL r8, 24(r9) li r8, 0 mtspr SPRN_TCR, r8 @@ -1103,6 +1105,8 @@ _GLOBAL(fsl_booke_deep_sleep_resume) mtlr r4 lwz r4, 8(r3) mtmsr r4 + lwz r4, 24(r3) + mtcr r4 blr @@ -1155,6 +1159,8 @@ _GLOBAL(fsl_booke_deep_sleep_resume) mtlr r4 ld r4, 8(r3) mtmsr r4 + ld r4, 24(r3) + mtcr r4 blr |