From d47855b5967c6d97b1a503fc7674d8ee2ee5bea0 Mon Sep 17 00:00:00 2001 From: Ranjani Vaidyanathan Date: Mon, 21 May 2012 09:37:03 -0500 Subject: [PATCH] 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 --- arch/arm/mach-mx6/pm.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) 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; -- 2.39.5