aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);