diff options
author | Tomasz Figa <t.figa@samsung.com> | 2014-02-13 18:16:01 -0500 |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2014-02-13 18:16:01 -0500 |
commit | 08c0d829d8835061981371f325e9c2b7f887c418 (patch) | |
tree | e738df498e87d78f9f5cab880f1b383fdc463533 | |
parent | 388c78851ee3c1fa6e80e9e06dc3bb9d77fb5f55 (diff) |
clk: samsung: s3c64xx: 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-s3c64xx.c | 79 |
1 files changed, 68 insertions, 11 deletions
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index 8e27aee6887e..d3fbfa566974 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/clk-provider.h> | 13 | #include <linux/clk-provider.h> |
14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
16 | #include <linux/syscore_ops.h> | ||
16 | 17 | ||
17 | #include <dt-bindings/clock/samsung,s3c64xx-clock.h> | 18 | #include <dt-bindings/clock/samsung,s3c64xx-clock.h> |
18 | 19 | ||
@@ -61,6 +62,13 @@ enum s3c64xx_plls { | |||
61 | apll, mpll, epll, | 62 | apll, mpll, epll, |
62 | }; | 63 | }; |
63 | 64 | ||
65 | static void __iomem *reg_base; | ||
66 | static bool is_s3c6400; | ||
67 | |||
68 | #ifdef CONFIG_PM_SLEEP | ||
69 | static struct samsung_clk_reg_dump *s3c64xx_save_common; | ||
70 | static struct samsung_clk_reg_dump *s3c64xx_save_soc; | ||
71 | |||
64 | /* | 72 | /* |
65 | * List of controller registers to be saved and restored during | 73 | * List of controller registers to be saved and restored during |
66 | * a suspend/resume cycle. | 74 | * a suspend/resume cycle. |
@@ -87,6 +95,60 @@ static unsigned long s3c6410_clk_regs[] __initdata = { | |||
87 | MEM0_GATE, | 95 | MEM0_GATE, |
88 | }; | 96 | }; |
89 | 97 | ||
98 | static int s3c64xx_clk_suspend(void) | ||
99 | { | ||
100 | samsung_clk_save(reg_base, s3c64xx_save_common, | ||
101 | ARRAY_SIZE(s3c64xx_clk_regs)); | ||
102 | |||
103 | if (!is_s3c6400) | ||
104 | samsung_clk_save(reg_base, s3c64xx_save_soc, | ||
105 | ARRAY_SIZE(s3c6410_clk_regs)); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static void s3c64xx_clk_resume(void) | ||
111 | { | ||
112 | samsung_clk_restore(reg_base, s3c64xx_save_common, | ||
113 | ARRAY_SIZE(s3c64xx_clk_regs)); | ||
114 | |||
115 | if (!is_s3c6400) | ||
116 | samsung_clk_restore(reg_base, s3c64xx_save_soc, | ||
117 | ARRAY_SIZE(s3c6410_clk_regs)); | ||
118 | } | ||
119 | |||
120 | static struct syscore_ops s3c64xx_clk_syscore_ops = { | ||
121 | .suspend = s3c64xx_clk_suspend, | ||
122 | .resume = s3c64xx_clk_resume, | ||
123 | }; | ||
124 | |||
125 | static void s3c64xx_clk_sleep_init(void) | ||
126 | { | ||
127 | s3c64xx_save_common = samsung_clk_alloc_reg_dump(s3c64xx_clk_regs, | ||
128 | ARRAY_SIZE(s3c64xx_clk_regs)); | ||
129 | if (!s3c64xx_save_common) | ||
130 | goto err_warn; | ||
131 | |||
132 | if (!is_s3c6400) { | ||
133 | s3c64xx_save_soc = samsung_clk_alloc_reg_dump(s3c6410_clk_regs, | ||
134 | ARRAY_SIZE(s3c6410_clk_regs)); | ||
135 | if (!s3c64xx_save_soc) | ||
136 | goto err_soc; | ||
137 | } | ||
138 | |||
139 | register_syscore_ops(&s3c64xx_clk_syscore_ops); | ||
140 | return; | ||
141 | |||
142 | err_soc: | ||
143 | kfree(s3c64xx_save_common); | ||
144 | err_warn: | ||
145 | pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", | ||
146 | __func__); | ||
147 | } | ||
148 | #else | ||
149 | static void s3c64xx_clk_sleep_init(void) {} | ||
150 | #endif | ||
151 | |||
90 | /* List of parent clocks common for all S3C64xx SoCs. */ | 152 | /* List of parent clocks common for all S3C64xx SoCs. */ |
91 | PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" }; | 153 | PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" }; |
92 | PNAME(uart_p) = { "mout_epll", "dout_mpll" }; | 154 | PNAME(uart_p) = { "mout_epll", "dout_mpll" }; |
@@ -391,11 +453,11 @@ static void __init s3c64xx_clk_register_fixed_ext(unsigned long fin_pll_f, | |||
391 | 453 | ||
392 | /* Register s3c64xx clocks. */ | 454 | /* Register s3c64xx clocks. */ |
393 | void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, | 455 | void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, |
394 | unsigned long xusbxti_f, bool is_s3c6400, | 456 | unsigned long xusbxti_f, bool s3c6400, |
395 | void __iomem *reg_base) | 457 | void __iomem *base) |
396 | { | 458 | { |
397 | unsigned long *soc_regs = NULL; | 459 | reg_base = base; |
398 | unsigned long nr_soc_regs = 0; | 460 | is_s3c6400 = s3c6400; |
399 | 461 | ||
400 | if (np) { | 462 | if (np) { |
401 | reg_base = of_iomap(np, 0); | 463 | reg_base = of_iomap(np, 0); |
@@ -403,13 +465,7 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, | |||
403 | panic("%s: failed to map registers\n", __func__); | 465 | panic("%s: failed to map registers\n", __func__); |
404 | } | 466 | } |
405 | 467 | ||
406 | if (!is_s3c6400) { | 468 | samsung_clk_init(np, reg_base, NR_CLKS, NULL, 0, NULL, 0); |
407 | soc_regs = s3c6410_clk_regs; | ||
408 | nr_soc_regs = ARRAY_SIZE(s3c6410_clk_regs); | ||
409 | } | ||
410 | |||
411 | samsung_clk_init(np, reg_base, NR_CLKS, s3c64xx_clk_regs, | ||
412 | ARRAY_SIZE(s3c64xx_clk_regs), soc_regs, nr_soc_regs); | ||
413 | 469 | ||
414 | /* Register external clocks. */ | 470 | /* Register external clocks. */ |
415 | if (!np) | 471 | if (!np) |
@@ -452,6 +508,7 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, | |||
452 | 508 | ||
453 | samsung_clk_register_alias(s3c64xx_clock_aliases, | 509 | samsung_clk_register_alias(s3c64xx_clock_aliases, |
454 | ARRAY_SIZE(s3c64xx_clock_aliases)); | 510 | ARRAY_SIZE(s3c64xx_clock_aliases)); |
511 | s3c64xx_clk_sleep_init(); | ||
455 | 512 | ||
456 | pr_info("%s clocks: apll = %lu, mpll = %lu\n" | 513 | pr_info("%s clocks: apll = %lu, mpll = %lu\n" |
457 | "\tepll = %lu, arm_clk = %lu\n", | 514 | "\tepll = %lu, arm_clk = %lu\n", |