diff options
author | Tomasz Figa <t.figa@samsung.com> | 2014-02-13 18:16:00 -0500 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2014-02-13 18:16:00 -0500 |
commit | b7b647be157c9503aec9ce3c7d7e86205a6c39dc (patch) | |
tree | 5e1458a5bc3ecb206bc48b7676e7440db06f4d69 | |
parent | 3ccefbd2291d6ee59f242c05266e241c5e33667e (diff) |
clk: samsung: exynos4: Move suspend/resume handling to SoC driver
Since there are multiple differences in how suspend/resume of particular
Exynos SoCs must be handled, SoC driver is better place for
suspend/resume handlers and so this patch moves them.
Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: Thomas Abraham <thomas.ab@samsung.com>
Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r-- | drivers/clk/samsung/clk-exynos4.c | 90 |
1 files changed, 80 insertions, 10 deletions
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 12a9f28f9f17..325f29248af5 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/clk-provider.h> | 16 | #include <linux/clk-provider.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
19 | #include <linux/syscore_ops.h> | ||
19 | 20 | ||
20 | #include "clk.h" | 21 | #include "clk.h" |
21 | 22 | ||
@@ -130,6 +131,16 @@ enum exynos4_plls { | |||
130 | nr_plls /* number of PLLs */ | 131 | nr_plls /* number of PLLs */ |
131 | }; | 132 | }; |
132 | 133 | ||
134 | static void __iomem *reg_base; | ||
135 | static enum exynos4_soc exynos4_soc; | ||
136 | |||
137 | /* | ||
138 | * Support for CMU save/restore across system suspends | ||
139 | */ | ||
140 | #ifdef CONFIG_PM_SLEEP | ||
141 | static struct samsung_clk_reg_dump *exynos4_save_common; | ||
142 | static struct samsung_clk_reg_dump *exynos4_save_soc; | ||
143 | |||
133 | /* | 144 | /* |
134 | * list of controller registers to be saved and restored during a | 145 | * list of controller registers to be saved and restored during a |
135 | * suspend/resume cycle. | 146 | * suspend/resume cycle. |
@@ -227,6 +238,70 @@ static unsigned long exynos4_clk_regs[] __initdata = { | |||
227 | GATE_IP_CPU, | 238 | GATE_IP_CPU, |
228 | }; | 239 | }; |
229 | 240 | ||
241 | static int exynos4_clk_suspend(void) | ||
242 | { | ||
243 | samsung_clk_save(reg_base, exynos4_save_common, | ||
244 | ARRAY_SIZE(exynos4_clk_regs)); | ||
245 | |||
246 | if (exynos4_soc == EXYNOS4210) | ||
247 | samsung_clk_save(reg_base, exynos4_save_soc, | ||
248 | ARRAY_SIZE(exynos4210_clk_save)); | ||
249 | else | ||
250 | samsung_clk_save(reg_base, exynos4_save_soc, | ||
251 | ARRAY_SIZE(exynos4x12_clk_save)); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static void exynos4_clk_resume(void) | ||
257 | { | ||
258 | samsung_clk_restore(reg_base, exynos4_save_common, | ||
259 | ARRAY_SIZE(exynos4_clk_regs)); | ||
260 | |||
261 | if (exynos4_soc == EXYNOS4210) | ||
262 | samsung_clk_restore(reg_base, exynos4_save_soc, | ||
263 | ARRAY_SIZE(exynos4210_clk_save)); | ||
264 | else | ||
265 | samsung_clk_restore(reg_base, exynos4_save_soc, | ||
266 | ARRAY_SIZE(exynos4x12_clk_save)); | ||
267 | } | ||
268 | |||
269 | static struct syscore_ops exynos4_clk_syscore_ops = { | ||
270 | .suspend = exynos4_clk_suspend, | ||
271 | .resume = exynos4_clk_resume, | ||
272 | }; | ||
273 | |||
274 | static void exynos4_clk_sleep_init(void) | ||
275 | { | ||
276 | exynos4_save_common = samsung_clk_alloc_reg_dump(exynos4_clk_regs, | ||
277 | ARRAY_SIZE(exynos4_clk_regs)); | ||
278 | if (!exynos4_save_common) | ||
279 | goto err_warn; | ||
280 | |||
281 | if (exynos4_soc == EXYNOS4210) | ||
282 | exynos4_save_soc = samsung_clk_alloc_reg_dump( | ||
283 | exynos4210_clk_save, | ||
284 | ARRAY_SIZE(exynos4210_clk_save)); | ||
285 | else | ||
286 | exynos4_save_soc = samsung_clk_alloc_reg_dump( | ||
287 | exynos4x12_clk_save, | ||
288 | ARRAY_SIZE(exynos4x12_clk_save)); | ||
289 | if (!exynos4_save_soc) | ||
290 | goto err_common; | ||
291 | |||
292 | register_syscore_ops(&exynos4_clk_syscore_ops); | ||
293 | return; | ||
294 | |||
295 | err_common: | ||
296 | kfree(exynos4_save_common); | ||
297 | err_warn: | ||
298 | pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", | ||
299 | __func__); | ||
300 | } | ||
301 | #else | ||
302 | static void exynos4_clk_sleep_init(void) {} | ||
303 | #endif | ||
304 | |||
230 | /* list of all parent clock list */ | 305 | /* list of all parent clock list */ |
231 | PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; | 306 | PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; |
232 | PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", }; | 307 | PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", }; |
@@ -1039,22 +1114,15 @@ static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = { | |||
1039 | 1114 | ||
1040 | /* register exynos4 clocks */ | 1115 | /* register exynos4 clocks */ |
1041 | static void __init exynos4_clk_init(struct device_node *np, | 1116 | static void __init exynos4_clk_init(struct device_node *np, |
1042 | enum exynos4_soc exynos4_soc) | 1117 | enum exynos4_soc soc) |
1043 | { | 1118 | { |
1044 | void __iomem *reg_base; | 1119 | exynos4_soc = soc; |
1045 | 1120 | ||
1046 | reg_base = of_iomap(np, 0); | 1121 | reg_base = of_iomap(np, 0); |
1047 | if (!reg_base) | 1122 | if (!reg_base) |
1048 | panic("%s: failed to map registers\n", __func__); | 1123 | panic("%s: failed to map registers\n", __func__); |
1049 | 1124 | ||
1050 | if (exynos4_soc == EXYNOS4210) | 1125 | samsung_clk_init(np, reg_base, CLK_NR_CLKS, NULL, 0, NULL, 0); |
1051 | samsung_clk_init(np, reg_base, CLK_NR_CLKS, | ||
1052 | exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), | ||
1053 | exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save)); | ||
1054 | else | ||
1055 | samsung_clk_init(np, reg_base, CLK_NR_CLKS, | ||
1056 | exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), | ||
1057 | exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save)); | ||
1058 | 1126 | ||
1059 | samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks, | 1127 | samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks, |
1060 | ARRAY_SIZE(exynos4_fixed_rate_ext_clks), | 1128 | ARRAY_SIZE(exynos4_fixed_rate_ext_clks), |
@@ -1127,6 +1195,8 @@ static void __init exynos4_clk_init(struct device_node *np, | |||
1127 | samsung_clk_register_alias(exynos4_aliases, | 1195 | samsung_clk_register_alias(exynos4_aliases, |
1128 | ARRAY_SIZE(exynos4_aliases)); | 1196 | ARRAY_SIZE(exynos4_aliases)); |
1129 | 1197 | ||
1198 | exynos4_clk_sleep_init(); | ||
1199 | |||
1130 | pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" | 1200 | pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" |
1131 | "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n", | 1201 | "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n", |
1132 | exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12", | 1202 | exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12", |