aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNaveen Krishna Ch <naveenkrishna.ch@gmail.com>2014-09-22 00:47:02 -0400
committerSylwester Nawrocki <s.nawrocki@samsung.com>2014-10-31 05:45:45 -0400
commit16a9013b83b5106c83cf3caf9ba0d94e54dbebba (patch)
tree383dcd45ac7f1d56d15d90f596aa6a3759b85bf0
parent0c23e2af6792d7b71d79dd4052c5c93512c5c84d (diff)
clk: samsung: Factor out the common code to clk.c
While adding clock support for Exynos5260, the infrastructure to register multiple clock controllers was introduced. Factor out the support for registering multiple clock controller from Exynos5260 clock code to common samsung clock code so that it can be used by other Exynos SoC which have multiple clock controllers. Signed-off-by: Naveen Krishna Ch <naveenkrishna.ch@gmail.com> Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> Reviewed-by: Thomas Abraham <thomas.ab@samsung.com> Tested-by: Thomas Abraham <thomas.ab@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
-rw-r--r--drivers/clk/samsung/clk-exynos5260.c185
-rw-r--r--drivers/clk/samsung/clk.c95
-rw-r--r--drivers/clk/samsung/clk.h34
3 files changed, 155 insertions, 159 deletions
diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c
index 2527e39aadcf..e2e5193d1049 100644
--- a/drivers/clk/samsung/clk-exynos5260.c
+++ b/drivers/clk/samsung/clk-exynos5260.c
@@ -11,10 +11,8 @@
11 11
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/clkdev.h> 13#include <linux/clkdev.h>
14#include <linux/clk-provider.h>
15#include <linux/of.h> 14#include <linux/of.h>
16#include <linux/of_address.h> 15#include <linux/of_address.h>
17#include <linux/syscore_ops.h>
18 16
19#include "clk-exynos5260.h" 17#include "clk-exynos5260.h"
20#include "clk.h" 18#include "clk.h"
@@ -22,39 +20,6 @@
22 20
23#include <dt-bindings/clock/exynos5260-clk.h> 21#include <dt-bindings/clock/exynos5260-clk.h>
24 22
25static LIST_HEAD(clock_reg_cache_list);
26
27struct exynos5260_clock_reg_cache {
28 struct list_head node;
29 void __iomem *reg_base;
30 struct samsung_clk_reg_dump *rdump;
31 unsigned int rd_num;
32};
33
34struct exynos5260_cmu_info {
35 /* list of pll clocks and respective count */
36 struct samsung_pll_clock *pll_clks;
37 unsigned int nr_pll_clks;
38 /* list of mux clocks and respective count */
39 struct samsung_mux_clock *mux_clks;
40 unsigned int nr_mux_clks;
41 /* list of div clocks and respective count */
42 struct samsung_div_clock *div_clks;
43 unsigned int nr_div_clks;
44 /* list of gate clocks and respective count */
45 struct samsung_gate_clock *gate_clks;
46 unsigned int nr_gate_clks;
47 /* list of fixed clocks and respective count */
48 struct samsung_fixed_rate_clock *fixed_clks;
49 unsigned int nr_fixed_clks;
50 /* total number of clocks with IDs assigned*/
51 unsigned int nr_clk_ids;
52
53 /* list and number of clocks registers */
54 unsigned long *clk_regs;
55 unsigned int nr_clk_regs;
56};
57
58/* 23/*
59 * Applicable for all 2550 Type PLLS for Exynos5260, listed below 24 * Applicable for all 2550 Type PLLS for Exynos5260, listed below
60 * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL. 25 * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL.
@@ -113,104 +78,6 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = {
113 PLL_36XX_RATE(66000000, 176, 2, 5, 0), 78 PLL_36XX_RATE(66000000, 176, 2, 5, 0),
114}; 79};
115 80
116#ifdef CONFIG_PM_SLEEP
117
118static int exynos5260_clk_suspend(void)
119{
120 struct exynos5260_clock_reg_cache *cache;
121
122 list_for_each_entry(cache, &clock_reg_cache_list, node)
123 samsung_clk_save(cache->reg_base, cache->rdump,
124 cache->rd_num);
125
126 return 0;
127}
128
129static void exynos5260_clk_resume(void)
130{
131 struct exynos5260_clock_reg_cache *cache;
132
133 list_for_each_entry(cache, &clock_reg_cache_list, node)
134 samsung_clk_restore(cache->reg_base, cache->rdump,
135 cache->rd_num);
136}
137
138static struct syscore_ops exynos5260_clk_syscore_ops = {
139 .suspend = exynos5260_clk_suspend,
140 .resume = exynos5260_clk_resume,
141};
142
143static void exynos5260_clk_sleep_init(void __iomem *reg_base,
144 unsigned long *rdump,
145 unsigned long nr_rdump)
146{
147 struct exynos5260_clock_reg_cache *reg_cache;
148
149 reg_cache = kzalloc(sizeof(struct exynos5260_clock_reg_cache),
150 GFP_KERNEL);
151 if (!reg_cache)
152 panic("could not allocate register cache.\n");
153
154 reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump);
155
156 if (!reg_cache->rdump)
157 panic("could not allocate register dump storage.\n");
158
159 if (list_empty(&clock_reg_cache_list))
160 register_syscore_ops(&exynos5260_clk_syscore_ops);
161
162 reg_cache->rd_num = nr_rdump;
163 reg_cache->reg_base = reg_base;
164 list_add_tail(&reg_cache->node, &clock_reg_cache_list);
165}
166
167#else
168static void exynos5260_clk_sleep_init(void __iomem *reg_base,
169 unsigned long *rdump,
170 unsigned long nr_rdump){}
171#endif
172
173/*
174 * Common function which registers plls, muxes, dividers and gates
175 * for each CMU. It also add CMU register list to register cache.
176 */
177
178void __init exynos5260_cmu_register_one(struct device_node *np,
179 struct exynos5260_cmu_info *cmu)
180{
181 void __iomem *reg_base;
182 struct samsung_clk_provider *ctx;
183
184 reg_base = of_iomap(np, 0);
185 if (!reg_base)
186 panic("%s: failed to map registers\n", __func__);
187
188 ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
189 if (!ctx)
190 panic("%s: unable to alllocate ctx\n", __func__);
191
192 if (cmu->pll_clks)
193 samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
194 reg_base);
195 if (cmu->mux_clks)
196 samsung_clk_register_mux(ctx, cmu->mux_clks,
197 cmu->nr_mux_clks);
198 if (cmu->div_clks)
199 samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks);
200 if (cmu->gate_clks)
201 samsung_clk_register_gate(ctx, cmu->gate_clks,
202 cmu->nr_gate_clks);
203 if (cmu->fixed_clks)
204 samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,
205 cmu->nr_fixed_clks);
206 if (cmu->clk_regs)
207 exynos5260_clk_sleep_init(reg_base, cmu->clk_regs,
208 cmu->nr_clk_regs);
209
210 samsung_clk_of_add_provider(np, ctx);
211}
212
213
214/* CMU_AUD */ 81/* CMU_AUD */
215 82
216static unsigned long aud_clk_regs[] __initdata = { 83static unsigned long aud_clk_regs[] __initdata = {
@@ -268,7 +135,7 @@ struct samsung_gate_clock aud_gate_clks[] __initdata = {
268 135
269static void __init exynos5260_clk_aud_init(struct device_node *np) 136static void __init exynos5260_clk_aud_init(struct device_node *np)
270{ 137{
271 struct exynos5260_cmu_info cmu = {0}; 138 struct samsung_cmu_info cmu = {0};
272 139
273 cmu.mux_clks = aud_mux_clks; 140 cmu.mux_clks = aud_mux_clks;
274 cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks); 141 cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks);
@@ -280,7 +147,7 @@ static void __init exynos5260_clk_aud_init(struct device_node *np)
280 cmu.clk_regs = aud_clk_regs; 147 cmu.clk_regs = aud_clk_regs;
281 cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs); 148 cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs);
282 149
283 exynos5260_cmu_register_one(np, &cmu); 150 samsung_cmu_register_one(np, &cmu);
284} 151}
285 152
286CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud", 153CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud",
@@ -458,7 +325,7 @@ struct samsung_gate_clock disp_gate_clks[] __initdata = {
458 325
459static void __init exynos5260_clk_disp_init(struct device_node *np) 326static void __init exynos5260_clk_disp_init(struct device_node *np)
460{ 327{
461 struct exynos5260_cmu_info cmu = {0}; 328 struct samsung_cmu_info cmu = {0};
462 329
463 cmu.mux_clks = disp_mux_clks; 330 cmu.mux_clks = disp_mux_clks;
464 cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks); 331 cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks);
@@ -470,7 +337,7 @@ static void __init exynos5260_clk_disp_init(struct device_node *np)
470 cmu.clk_regs = disp_clk_regs; 337 cmu.clk_regs = disp_clk_regs;
471 cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs); 338 cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs);
472 339
473 exynos5260_cmu_register_one(np, &cmu); 340 samsung_cmu_register_one(np, &cmu);
474} 341}
475 342
476CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp", 343CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp",
@@ -522,7 +389,7 @@ static struct samsung_pll_clock egl_pll_clks[] __initdata = {
522 389
523static void __init exynos5260_clk_egl_init(struct device_node *np) 390static void __init exynos5260_clk_egl_init(struct device_node *np)
524{ 391{
525 struct exynos5260_cmu_info cmu = {0}; 392 struct samsung_cmu_info cmu = {0};
526 393
527 cmu.pll_clks = egl_pll_clks; 394 cmu.pll_clks = egl_pll_clks;
528 cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks); 395 cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks);
@@ -534,7 +401,7 @@ static void __init exynos5260_clk_egl_init(struct device_node *np)
534 cmu.clk_regs = egl_clk_regs; 401 cmu.clk_regs = egl_clk_regs;
535 cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs); 402 cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs);
536 403
537 exynos5260_cmu_register_one(np, &cmu); 404 samsung_cmu_register_one(np, &cmu);
538} 405}
539 406
540CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl", 407CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl",
@@ -624,7 +491,7 @@ struct samsung_gate_clock fsys_gate_clks[] __initdata = {
624 491
625static void __init exynos5260_clk_fsys_init(struct device_node *np) 492static void __init exynos5260_clk_fsys_init(struct device_node *np)
626{ 493{
627 struct exynos5260_cmu_info cmu = {0}; 494 struct samsung_cmu_info cmu = {0};
628 495
629 cmu.mux_clks = fsys_mux_clks; 496 cmu.mux_clks = fsys_mux_clks;
630 cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks); 497 cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks);
@@ -634,7 +501,7 @@ static void __init exynos5260_clk_fsys_init(struct device_node *np)
634 cmu.clk_regs = fsys_clk_regs; 501 cmu.clk_regs = fsys_clk_regs;
635 cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs); 502 cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs);
636 503
637 exynos5260_cmu_register_one(np, &cmu); 504 samsung_cmu_register_one(np, &cmu);
638} 505}
639 506
640CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys", 507CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys",
@@ -713,7 +580,7 @@ struct samsung_gate_clock g2d_gate_clks[] __initdata = {
713 580
714static void __init exynos5260_clk_g2d_init(struct device_node *np) 581static void __init exynos5260_clk_g2d_init(struct device_node *np)
715{ 582{
716 struct exynos5260_cmu_info cmu = {0}; 583 struct samsung_cmu_info cmu = {0};
717 584
718 cmu.mux_clks = g2d_mux_clks; 585 cmu.mux_clks = g2d_mux_clks;
719 cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks); 586 cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks);
@@ -725,7 +592,7 @@ static void __init exynos5260_clk_g2d_init(struct device_node *np)
725 cmu.clk_regs = g2d_clk_regs; 592 cmu.clk_regs = g2d_clk_regs;
726 cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs); 593 cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs);
727 594
728 exynos5260_cmu_register_one(np, &cmu); 595 samsung_cmu_register_one(np, &cmu);
729} 596}
730 597
731CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d", 598CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d",
@@ -774,7 +641,7 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = {
774 641
775static void __init exynos5260_clk_g3d_init(struct device_node *np) 642static void __init exynos5260_clk_g3d_init(struct device_node *np)
776{ 643{
777 struct exynos5260_cmu_info cmu = {0}; 644 struct samsung_cmu_info cmu = {0};
778 645
779 cmu.pll_clks = g3d_pll_clks; 646 cmu.pll_clks = g3d_pll_clks;
780 cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks); 647 cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks);
@@ -788,7 +655,7 @@ static void __init exynos5260_clk_g3d_init(struct device_node *np)
788 cmu.clk_regs = g3d_clk_regs; 655 cmu.clk_regs = g3d_clk_regs;
789 cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs); 656 cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs);
790 657
791 exynos5260_cmu_register_one(np, &cmu); 658 samsung_cmu_register_one(np, &cmu);
792} 659}
793 660
794CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d", 661CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d",
@@ -909,7 +776,7 @@ struct samsung_gate_clock gscl_gate_clks[] __initdata = {
909 776
910static void __init exynos5260_clk_gscl_init(struct device_node *np) 777static void __init exynos5260_clk_gscl_init(struct device_node *np)
911{ 778{
912 struct exynos5260_cmu_info cmu = {0}; 779 struct samsung_cmu_info cmu = {0};
913 780
914 cmu.mux_clks = gscl_mux_clks; 781 cmu.mux_clks = gscl_mux_clks;
915 cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks); 782 cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks);
@@ -921,7 +788,7 @@ static void __init exynos5260_clk_gscl_init(struct device_node *np)
921 cmu.clk_regs = gscl_clk_regs; 788 cmu.clk_regs = gscl_clk_regs;
922 cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs); 789 cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs);
923 790
924 exynos5260_cmu_register_one(np, &cmu); 791 samsung_cmu_register_one(np, &cmu);
925} 792}
926 793
927CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl", 794CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl",
@@ -1028,7 +895,7 @@ struct samsung_gate_clock isp_gate_clks[] __initdata = {
1028 895
1029static void __init exynos5260_clk_isp_init(struct device_node *np) 896static void __init exynos5260_clk_isp_init(struct device_node *np)
1030{ 897{
1031 struct exynos5260_cmu_info cmu = {0}; 898 struct samsung_cmu_info cmu = {0};
1032 899
1033 cmu.mux_clks = isp_mux_clks; 900 cmu.mux_clks = isp_mux_clks;
1034 cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks); 901 cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks);
@@ -1040,7 +907,7 @@ static void __init exynos5260_clk_isp_init(struct device_node *np)
1040 cmu.clk_regs = isp_clk_regs; 907 cmu.clk_regs = isp_clk_regs;
1041 cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs); 908 cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs);
1042 909
1043 exynos5260_cmu_register_one(np, &cmu); 910 samsung_cmu_register_one(np, &cmu);
1044} 911}
1045 912
1046CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp", 913CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp",
@@ -1092,7 +959,7 @@ static struct samsung_pll_clock kfc_pll_clks[] __initdata = {
1092 959
1093static void __init exynos5260_clk_kfc_init(struct device_node *np) 960static void __init exynos5260_clk_kfc_init(struct device_node *np)
1094{ 961{
1095 struct exynos5260_cmu_info cmu = {0}; 962 struct samsung_cmu_info cmu = {0};
1096 963
1097 cmu.pll_clks = kfc_pll_clks; 964 cmu.pll_clks = kfc_pll_clks;
1098 cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks); 965 cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks);
@@ -1104,7 +971,7 @@ static void __init exynos5260_clk_kfc_init(struct device_node *np)
1104 cmu.clk_regs = kfc_clk_regs; 971 cmu.clk_regs = kfc_clk_regs;
1105 cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs); 972 cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs);
1106 973
1107 exynos5260_cmu_register_one(np, &cmu); 974 samsung_cmu_register_one(np, &cmu);
1108} 975}
1109 976
1110CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc", 977CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc",
@@ -1148,7 +1015,7 @@ struct samsung_gate_clock mfc_gate_clks[] __initdata = {
1148 1015
1149static void __init exynos5260_clk_mfc_init(struct device_node *np) 1016static void __init exynos5260_clk_mfc_init(struct device_node *np)
1150{ 1017{
1151 struct exynos5260_cmu_info cmu = {0}; 1018 struct samsung_cmu_info cmu = {0};
1152 1019
1153 cmu.mux_clks = mfc_mux_clks; 1020 cmu.mux_clks = mfc_mux_clks;
1154 cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks); 1021 cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks);
@@ -1160,7 +1027,7 @@ static void __init exynos5260_clk_mfc_init(struct device_node *np)
1160 cmu.clk_regs = mfc_clk_regs; 1027 cmu.clk_regs = mfc_clk_regs;
1161 cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs); 1028 cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs);
1162 1029
1163 exynos5260_cmu_register_one(np, &cmu); 1030 samsung_cmu_register_one(np, &cmu);
1164} 1031}
1165 1032
1166CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc", 1033CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc",
@@ -1295,7 +1162,7 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = {
1295 1162
1296static void __init exynos5260_clk_mif_init(struct device_node *np) 1163static void __init exynos5260_clk_mif_init(struct device_node *np)
1297{ 1164{
1298 struct exynos5260_cmu_info cmu = {0}; 1165 struct samsung_cmu_info cmu = {0};
1299 1166
1300 cmu.pll_clks = mif_pll_clks; 1167 cmu.pll_clks = mif_pll_clks;
1301 cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks); 1168 cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks);
@@ -1309,7 +1176,7 @@ static void __init exynos5260_clk_mif_init(struct device_node *np)
1309 cmu.clk_regs = mif_clk_regs; 1176 cmu.clk_regs = mif_clk_regs;
1310 cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs); 1177 cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs);
1311 1178
1312 exynos5260_cmu_register_one(np, &cmu); 1179 samsung_cmu_register_one(np, &cmu);
1313} 1180}
1314 1181
1315CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif", 1182CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif",
@@ -1503,7 +1370,7 @@ struct samsung_gate_clock peri_gate_clks[] __initdata = {
1503 1370
1504static void __init exynos5260_clk_peri_init(struct device_node *np) 1371static void __init exynos5260_clk_peri_init(struct device_node *np)
1505{ 1372{
1506 struct exynos5260_cmu_info cmu = {0}; 1373 struct samsung_cmu_info cmu = {0};
1507 1374
1508 cmu.mux_clks = peri_mux_clks; 1375 cmu.mux_clks = peri_mux_clks;
1509 cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks); 1376 cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks);
@@ -1515,7 +1382,7 @@ static void __init exynos5260_clk_peri_init(struct device_node *np)
1515 cmu.clk_regs = peri_clk_regs; 1382 cmu.clk_regs = peri_clk_regs;
1516 cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs); 1383 cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs);
1517 1384
1518 exynos5260_cmu_register_one(np, &cmu); 1385 samsung_cmu_register_one(np, &cmu);
1519} 1386}
1520 1387
1521CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri", 1388CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri",
@@ -1959,7 +1826,7 @@ static struct samsung_pll_clock top_pll_clks[] __initdata = {
1959 1826
1960static void __init exynos5260_clk_top_init(struct device_node *np) 1827static void __init exynos5260_clk_top_init(struct device_node *np)
1961{ 1828{
1962 struct exynos5260_cmu_info cmu = {0}; 1829 struct samsung_cmu_info cmu = {0};
1963 1830
1964 cmu.pll_clks = top_pll_clks; 1831 cmu.pll_clks = top_pll_clks;
1965 cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks); 1832 cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks);
@@ -1975,7 +1842,7 @@ static void __init exynos5260_clk_top_init(struct device_node *np)
1975 cmu.clk_regs = top_clk_regs; 1842 cmu.clk_regs = top_clk_regs;
1976 cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs); 1843 cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs);
1977 1844
1978 exynos5260_cmu_register_one(np, &cmu); 1845 samsung_cmu_register_one(np, &cmu);
1979} 1846}
1980 1847
1981CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top", 1848CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top",
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index deab84d9f37d..a64823627d3a 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -14,6 +14,8 @@
14#include <linux/syscore_ops.h> 14#include <linux/syscore_ops.h>
15#include "clk.h" 15#include "clk.h"
16 16
17static LIST_HEAD(clock_reg_cache_list);
18
17void samsung_clk_save(void __iomem *base, 19void samsung_clk_save(void __iomem *base,
18 struct samsung_clk_reg_dump *rd, 20 struct samsung_clk_reg_dump *rd,
19 unsigned int num_regs) 21 unsigned int num_regs)
@@ -313,3 +315,96 @@ unsigned long _get_rate(const char *clk_name)
313 315
314 return clk_get_rate(clk); 316 return clk_get_rate(clk);
315} 317}
318
319#ifdef CONFIG_PM_SLEEP
320static int samsung_clk_suspend(void)
321{
322 struct samsung_clock_reg_cache *reg_cache;
323
324 list_for_each_entry(reg_cache, &clock_reg_cache_list, node)
325 samsung_clk_save(reg_cache->reg_base, reg_cache->rdump,
326 reg_cache->rd_num);
327 return 0;
328}
329
330static void samsung_clk_resume(void)
331{
332 struct samsung_clock_reg_cache *reg_cache;
333
334 list_for_each_entry(reg_cache, &clock_reg_cache_list, node)
335 samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump,
336 reg_cache->rd_num);
337}
338
339static struct syscore_ops samsung_clk_syscore_ops = {
340 .suspend = samsung_clk_suspend,
341 .resume = samsung_clk_resume,
342};
343
344static void samsung_clk_sleep_init(void __iomem *reg_base,
345 const unsigned long *rdump,
346 unsigned long nr_rdump)
347{
348 struct samsung_clock_reg_cache *reg_cache;
349
350 reg_cache = kzalloc(sizeof(struct samsung_clock_reg_cache),
351 GFP_KERNEL);
352 if (!reg_cache)
353 panic("could not allocate register reg_cache.\n");
354 reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump);
355
356 if (!reg_cache->rdump)
357 panic("could not allocate register dump storage.\n");
358
359 if (list_empty(&clock_reg_cache_list))
360 register_syscore_ops(&samsung_clk_syscore_ops);
361
362 reg_cache->reg_base = reg_base;
363 reg_cache->rd_num = nr_rdump;
364 list_add_tail(&reg_cache->node, &clock_reg_cache_list);
365}
366
367#else
368static void samsung_clk_sleep_init(void __iomem *reg_base,
369 const unsigned long *rdump,
370 unsigned long nr_rdump) {}
371#endif
372
373/*
374 * Common function which registers plls, muxes, dividers and gates
375 * for each CMU. It also add CMU register list to register cache.
376 */
377void __init samsung_cmu_register_one(struct device_node *np,
378 struct samsung_cmu_info *cmu)
379{
380 void __iomem *reg_base;
381 struct samsung_clk_provider *ctx;
382
383 reg_base = of_iomap(np, 0);
384 if (!reg_base)
385 panic("%s: failed to map registers\n", __func__);
386
387 ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
388 if (!ctx)
389 panic("%s: unable to alllocate ctx\n", __func__);
390
391 if (cmu->pll_clks)
392 samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
393 reg_base);
394 if (cmu->mux_clks)
395 samsung_clk_register_mux(ctx, cmu->mux_clks,
396 cmu->nr_mux_clks);
397 if (cmu->div_clks)
398 samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks);
399 if (cmu->gate_clks)
400 samsung_clk_register_gate(ctx, cmu->gate_clks,
401 cmu->nr_gate_clks);
402 if (cmu->fixed_clks)
403 samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,
404 cmu->nr_fixed_clks);
405 if (cmu->clk_regs)
406 samsung_clk_sleep_init(reg_base, cmu->clk_regs,
407 cmu->nr_clk_regs);
408
409 samsung_clk_of_add_provider(np, ctx);
410}
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 66ab36b5cef1..b3d0f4d97f97 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -324,6 +324,37 @@ struct samsung_pll_clock {
324 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \ 324 __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
325 _lock, _con, _rtable, _alias) 325 _lock, _con, _rtable, _alias)
326 326
327struct samsung_clock_reg_cache {
328 struct list_head node;
329 void __iomem *reg_base;
330 struct samsung_clk_reg_dump *rdump;
331 unsigned int rd_num;
332};
333
334struct samsung_cmu_info {
335 /* list of pll clocks and respective count */
336 struct samsung_pll_clock *pll_clks;
337 unsigned int nr_pll_clks;
338 /* list of mux clocks and respective count */
339 struct samsung_mux_clock *mux_clks;
340 unsigned int nr_mux_clks;
341 /* list of div clocks and respective count */
342 struct samsung_div_clock *div_clks;
343 unsigned int nr_div_clks;
344 /* list of gate clocks and respective count */
345 struct samsung_gate_clock *gate_clks;
346 unsigned int nr_gate_clks;
347 /* list of fixed clocks and respective count */
348 struct samsung_fixed_rate_clock *fixed_clks;
349 unsigned int nr_fixed_clks;
350 /* total number of clocks with IDs assigned*/
351 unsigned int nr_clk_ids;
352
353 /* list and number of clocks registers */
354 unsigned long *clk_regs;
355 unsigned int nr_clk_regs;
356};
357
327extern struct samsung_clk_provider *__init samsung_clk_init( 358extern struct samsung_clk_provider *__init samsung_clk_init(
328 struct device_node *np, void __iomem *base, 359 struct device_node *np, void __iomem *base,
329 unsigned long nr_clks); 360 unsigned long nr_clks);
@@ -362,6 +393,9 @@ extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
362 struct samsung_pll_clock *pll_list, 393 struct samsung_pll_clock *pll_list,
363 unsigned int nr_clk, void __iomem *base); 394 unsigned int nr_clk, void __iomem *base);
364 395
396extern void __init samsung_cmu_register_one(struct device_node *,
397 struct samsung_cmu_info *);
398
365extern unsigned long _get_rate(const char *clk_name); 399extern unsigned long _get_rate(const char *clk_name);
366 400
367extern void samsung_clk_save(void __iomem *base, 401extern void samsung_clk_save(void __iomem *base,