From: Ranjani Vaidyanathan Date: Mon, 21 May 2012 14:37:03 +0000 (-0500) Subject: ENGR00210469 MX6q - Fix suspend/resume failure. X-Git-Tag: v3.0.35-fsl~987 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=d47855b5967c6d97b1a503fc7674d8ee2ee5bea0;p=karo-tx-linux.git 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 --- 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;