diff options
author | Ranjani Vaidyanathan <ra5478@freescale.com> | 2012-05-21 09:37:03 -0500 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2012-07-20 13:37:58 +0800 |
commit | facf288b8d24109b36aa9dfe3993b925b15597fe (patch) | |
tree | 797ed5b24bf76e51749cd9e29423f438b7461a00 /arch | |
parent | 4bc54b1515b3cb1c56133f3d6101aa311d97ac9b (diff) |
ENGR00210469 MX6q - Fix suspend/resume failure.
Sourcing AXI_CLK from PLL3_PFD_540M causes the system to
hang on resuming from STOP mode.
The main issue is that PFDs may sometimes hang/freeze
when their parent PLLs are powered on and then relocked
when exiting from STOP mode. To avoid this, PFDs must
be disabled before entering STOP and enabled after resume.
The fix is to move axi_clk to periph_clk before system
enters STOP and then restore it back to PLL3_PFD_540M
after resume.
Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-mx6/pm.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c index 271f3c37777d..229de6651266 100644 --- a/arch/arm/mach-mx6/pm.c +++ b/arch/arm/mach-mx6/pm.c @@ -66,6 +66,10 @@ #define ANATOP_REG_CORE_OFFSET 0x140 static struct clk *cpu_clk; +static struct clk *axi_clk; +static struct clk *periph_clk; +static struct clk *axi_org_parent; + static struct pm_platform_data *pm_data; #if defined(CONFIG_CPU_FREQ) @@ -324,6 +328,9 @@ static int mx6_suspend_enter(suspend_state_t state) return -EINVAL; } + axi_org_parent = clk_get_parent(axi_clk); + clk_set_parent(axi_clk, periph_clk); + if (state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY) { if (pm_data && pm_data->suspend_enter) pm_data->suspend_enter(); @@ -347,6 +354,7 @@ static int mx6_suspend_enter(suspend_state_t state) usb_power_up_handler(); gpu_power_up(); } + mx6_suspend_restore(); if (pm_data && pm_data->suspend_exit) @@ -354,6 +362,7 @@ static int mx6_suspend_enter(suspend_state_t state) } else { cpu_do_idle(); } + clk_set_parent(axi_clk, axi_org_parent); return 0; } @@ -449,6 +458,17 @@ static int __init pm_init(void) printk(KERN_DEBUG "%s: failed to get cpu_clk\n", __func__); return PTR_ERR(cpu_clk); } + axi_clk = clk_get(NULL, "axi_clk"); + if (IS_ERR(axi_clk)) { + printk(KERN_DEBUG "%s: failed to get axi_clk\n", __func__); + return PTR_ERR(axi_clk); + } + periph_clk = clk_get(NULL, "periph_clk"); + if (IS_ERR(periph_clk)) { + printk(KERN_DEBUG "%s: failed to get periph_clk\n", __func__); + return PTR_ERR(periph_clk); + } + printk(KERN_INFO "PM driver module loaded\n"); return 0; |