aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2012-06-11 11:29:54 -0400
committerMike Turquette <mturquette@linaro.org>2012-07-11 20:58:44 -0400
commit91b87a4795c42b97b8d18c3757eff352458ecef4 (patch)
tree4f50b6f6176db84294be1d114979f1375e90dafc /drivers/clk
parentd59fdcfc63a2d15b11dde10a85233b95cee0ad2e (diff)
clk: add versatile ICST307 driver
The ICST307 VCO clock has a shared driver in the ARM architecture. This patch provides a wrapper into the common clock framework so we can use the implementation in the ARM architecture without duplicating the code until all ARM platforms using this VCO are moved over. At that point we can merge the driver from the ARM platform into the generic file altogether. Cc: Russell King <linux@arm.linux.org.uk> Cc: Mike Turquette <mturquette@ti.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> [mturquette@linaro.org: removed versatile Kconfig] Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/versatile/Makefile2
-rw-r--r--drivers/clk/versatile/clk-icst.c100
-rw-r--r--drivers/clk/versatile/clk-icst.h10
4 files changed, 113 insertions, 0 deletions
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 35d9fb44c814..a4d67d7a7534 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \
6obj-$(CONFIG_ARCH_MXS) += mxs/ 6obj-$(CONFIG_ARCH_MXS) += mxs/
7obj-$(CONFIG_PLAT_SPEAR) += spear/ 7obj-$(CONFIG_PLAT_SPEAR) += spear/
8obj-$(CONFIG_ARCH_U300) += clk-u300.o 8obj-$(CONFIG_ARCH_U300) += clk-u300.o
9obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/
9 10
10# Chip specific 11# Chip specific
11obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o 12obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile
new file mode 100644
index 000000000000..a83539b41787
--- /dev/null
+++ b/drivers/clk/versatile/Makefile
@@ -0,0 +1,2 @@
1# Makefile for Versatile-specific clocks
2obj-$(CONFIG_ICST) += clk-icst.o
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
new file mode 100644
index 000000000000..f555b50a5fa5
--- /dev/null
+++ b/drivers/clk/versatile/clk-icst.c
@@ -0,0 +1,100 @@
1/*
2 * Driver for the ICST307 VCO clock found in the ARM Reference designs.
3 * We wrap the custom interface from <asm/hardware/icst.h> into the generic
4 * clock framework.
5 *
6 * TODO: when all ARM reference designs are migrated to generic clocks, the
7 * ICST clock code from the ARM tree should probably be merged into this
8 * file.
9 */
10#include <linux/clk.h>
11#include <linux/clkdev.h>
12#include <linux/err.h>
13#include <linux/clk-provider.h>
14
15#include "clk-icst.h"
16
17/**
18 * struct clk_icst - ICST VCO clock wrapper
19 * @hw: corresponding clock hardware entry
20 * @params: parameters for this ICST instance
21 * @rate: current rate
22 * @setvco: function to commit ICST settings to hardware
23 */
24struct clk_icst {
25 struct clk_hw hw;
26 const struct icst_params *params;
27 unsigned long rate;
28 struct icst_vco (*getvco)(void);
29 void (*setvco)(struct icst_vco);
30};
31
32#define to_icst(_hw) container_of(_hw, struct clk_icst, hw)
33
34static unsigned long icst_recalc_rate(struct clk_hw *hw,
35 unsigned long parent_rate)
36{
37 struct clk_icst *icst = to_icst(hw);
38 struct icst_vco vco;
39
40 vco = icst->getvco();
41 icst->rate = icst_hz(icst->params, vco);
42 return icst->rate;
43}
44
45static long icst_round_rate(struct clk_hw *hw, unsigned long rate,
46 unsigned long *prate)
47{
48 struct clk_icst *icst = to_icst(hw);
49 struct icst_vco vco;
50
51 vco = icst_hz_to_vco(icst->params, rate);
52 return icst_hz(icst->params, vco);
53}
54
55static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
56 unsigned long parent_rate)
57{
58 struct clk_icst *icst = to_icst(hw);
59 struct icst_vco vco;
60
61 vco = icst_hz_to_vco(icst->params, rate);
62 icst->rate = icst_hz(icst->params, vco);
63 icst->setvco(vco);
64 return 0;
65}
66
67static const struct clk_ops icst_ops = {
68 .recalc_rate = icst_recalc_rate,
69 .round_rate = icst_round_rate,
70 .set_rate = icst_set_rate,
71};
72
73struct clk * __init icst_clk_register(struct device *dev,
74 const struct clk_icst_desc *desc)
75{
76 struct clk *clk;
77 struct clk_icst *icst;
78 struct clk_init_data init;
79
80 icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL);
81 if (!icst) {
82 pr_err("could not allocate ICST clock!\n");
83 return ERR_PTR(-ENOMEM);
84 }
85 init.name = "icst";
86 init.ops = &icst_ops;
87 init.flags = CLK_IS_ROOT;
88 init.parent_names = NULL;
89 init.num_parents = 0;
90 icst->hw.init = &init;
91 icst->params = desc->params;
92 icst->getvco = desc->getvco;
93 icst->setvco = desc->setvco;
94
95 clk = clk_register(dev, &icst->hw);
96 if (IS_ERR(clk))
97 kfree(icst);
98
99 return clk;
100}
diff --git a/drivers/clk/versatile/clk-icst.h b/drivers/clk/versatile/clk-icst.h
new file mode 100644
index 000000000000..71b4c56c1410
--- /dev/null
+++ b/drivers/clk/versatile/clk-icst.h
@@ -0,0 +1,10 @@
1#include <asm/hardware/icst.h>
2
3struct clk_icst_desc {
4 const struct icst_params *params;
5 struct icst_vco (*getvco)(void);
6 void (*setvco)(struct icst_vco);
7};
8
9struct clk *icst_clk_register(struct device *dev,
10 const struct clk_icst_desc *desc);