aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/samsung/clk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/samsung/clk.c')
-rw-r--r--drivers/clk/samsung/clk.c71
1 files changed, 26 insertions, 45 deletions
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index f503f32e2f80..91bec3ebdc8f 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -21,64 +21,45 @@ static void __iomem *reg_base;
21static struct clk_onecell_data clk_data; 21static struct clk_onecell_data clk_data;
22#endif 22#endif
23 23
24#ifdef CONFIG_PM_SLEEP 24void samsung_clk_save(void __iomem *base,
25static struct samsung_clk_reg_dump *reg_dump; 25 struct samsung_clk_reg_dump *rd,
26static unsigned long nr_reg_dump; 26 unsigned int num_regs)
27
28static int samsung_clk_suspend(void)
29{ 27{
30 struct samsung_clk_reg_dump *rd = reg_dump; 28 for (; num_regs > 0; --num_regs, ++rd)
31 unsigned long i; 29 rd->value = readl(base + rd->offset);
32 30}
33 for (i = 0; i < nr_reg_dump; i++, rd++)
34 rd->value = __raw_readl(reg_base + rd->offset);
35 31
36 return 0; 32void samsung_clk_restore(void __iomem *base,
33 const struct samsung_clk_reg_dump *rd,
34 unsigned int num_regs)
35{
36 for (; num_regs > 0; --num_regs, ++rd)
37 writel(rd->value, base + rd->offset);
37} 38}
38 39
39static void samsung_clk_resume(void) 40struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
41 const unsigned long *rdump,
42 unsigned long nr_rdump)
40{ 43{
41 struct samsung_clk_reg_dump *rd = reg_dump; 44 struct samsung_clk_reg_dump *rd;
42 unsigned long i; 45 unsigned int i;
43 46
44 for (i = 0; i < nr_reg_dump; i++, rd++) 47 rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL);
45 __raw_writel(rd->value, reg_base + rd->offset); 48 if (!rd)
46} 49 return NULL;
50
51 for (i = 0; i < nr_rdump; ++i)
52 rd[i].offset = rdump[i];
47 53
48static struct syscore_ops samsung_clk_syscore_ops = { 54 return rd;
49 .suspend = samsung_clk_suspend, 55}
50 .resume = samsung_clk_resume,
51};
52#endif /* CONFIG_PM_SLEEP */
53 56
54/* setup the essentials required to support clock lookup using ccf */ 57/* setup the essentials required to support clock lookup using ccf */
55void __init samsung_clk_init(struct device_node *np, void __iomem *base, 58void __init samsung_clk_init(struct device_node *np, void __iomem *base,
56 unsigned long nr_clks, unsigned long *rdump, 59 unsigned long nr_clks)
57 unsigned long nr_rdump, unsigned long *soc_rdump,
58 unsigned long nr_soc_rdump)
59{ 60{
60 reg_base = base; 61 reg_base = base;
61 62
62#ifdef CONFIG_PM_SLEEP
63 if (rdump && nr_rdump) {
64 unsigned int idx;
65 reg_dump = kzalloc(sizeof(struct samsung_clk_reg_dump)
66 * (nr_rdump + nr_soc_rdump), GFP_KERNEL);
67 if (!reg_dump) {
68 pr_err("%s: memory alloc for register dump failed\n",
69 __func__);
70 return;
71 }
72
73 for (idx = 0; idx < nr_rdump; idx++)
74 reg_dump[idx].offset = rdump[idx];
75 for (idx = 0; idx < nr_soc_rdump; idx++)
76 reg_dump[nr_rdump + idx].offset = soc_rdump[idx];
77 nr_reg_dump = nr_rdump + nr_soc_rdump;
78 register_syscore_ops(&samsung_clk_syscore_ops);
79 }
80#endif
81
82 clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); 63 clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
83 if (!clk_table) 64 if (!clk_table)
84 panic("could not allocate clock lookup table\n"); 65 panic("could not allocate clock lookup table\n");