diff options
Diffstat (limited to 'arch/arm/mach-mx5/pm-imx5.c')
-rw-r--r-- | arch/arm/mach-mx5/pm-imx5.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/arch/arm/mach-mx5/pm-imx5.c b/arch/arm/mach-mx5/pm-imx5.c new file mode 100644 index 000000000000..e4529af0da72 --- /dev/null +++ b/arch/arm/mach-mx5/pm-imx5.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * | ||
4 | * The code contained herein is licensed under the GNU General Public | ||
5 | * License. You may obtain a copy of the GNU General Public License | ||
6 | * Version 2 or later at the following locations: | ||
7 | * | ||
8 | * http://www.opensource.org/licenses/gpl-license.html | ||
9 | * http://www.gnu.org/copyleft/gpl.html | ||
10 | */ | ||
11 | #include <linux/suspend.h> | ||
12 | #include <linux/clk.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <asm/cacheflush.h> | ||
16 | #include <asm/tlbflush.h> | ||
17 | #include <mach/system.h> | ||
18 | #include "crm_regs.h" | ||
19 | |||
20 | static struct clk *gpc_dvfs_clk; | ||
21 | |||
22 | static int mx5_suspend_enter(suspend_state_t state) | ||
23 | { | ||
24 | clk_enable(gpc_dvfs_clk); | ||
25 | switch (state) { | ||
26 | case PM_SUSPEND_MEM: | ||
27 | mx5_cpu_lp_set(STOP_POWER_OFF); | ||
28 | break; | ||
29 | case PM_SUSPEND_STANDBY: | ||
30 | mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); | ||
31 | break; | ||
32 | default: | ||
33 | return -EINVAL; | ||
34 | } | ||
35 | |||
36 | if (state == PM_SUSPEND_MEM) { | ||
37 | local_flush_tlb_all(); | ||
38 | flush_cache_all(); | ||
39 | |||
40 | /*clear the EMPGC0/1 bits */ | ||
41 | __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR); | ||
42 | __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR); | ||
43 | } | ||
44 | cpu_do_idle(); | ||
45 | clk_disable(gpc_dvfs_clk); | ||
46 | |||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | static int mx5_pm_valid(suspend_state_t state) | ||
51 | { | ||
52 | return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX); | ||
53 | } | ||
54 | |||
55 | static const struct platform_suspend_ops mx5_suspend_ops = { | ||
56 | .valid = mx5_pm_valid, | ||
57 | .enter = mx5_suspend_enter, | ||
58 | }; | ||
59 | |||
60 | static int __init mx5_pm_init(void) | ||
61 | { | ||
62 | if (gpc_dvfs_clk == NULL) | ||
63 | gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); | ||
64 | |||
65 | if (!IS_ERR(gpc_dvfs_clk)) { | ||
66 | if (cpu_is_mx51()) | ||
67 | suspend_set_ops(&mx5_suspend_ops); | ||
68 | } else | ||
69 | return -EPERM; | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | device_initcall(mx5_pm_init); | ||