summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorRanjani Vaidyanathan <ra5478@freescale.com>2012-05-21 09:37:03 -0500
committerJason Liu <r64343@freescale.com>2012-07-20 13:37:58 +0800
commitfacf288b8d24109b36aa9dfe3993b925b15597fe (patch)
tree797ed5b24bf76e51749cd9e29423f438b7461a00 /arch
parent4bc54b1515b3cb1c56133f3d6101aa311d97ac9b (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.c20
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;