aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/meson/clk-cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/meson/clk-cpu.c')
-rw-r--r--drivers/clk/meson/clk-cpu.c73
1 files changed, 4 insertions, 69 deletions
diff --git a/drivers/clk/meson/clk-cpu.c b/drivers/clk/meson/clk-cpu.c
index f7c30ea54ca8..f8b2b7efd016 100644
--- a/drivers/clk/meson/clk-cpu.c
+++ b/drivers/clk/meson/clk-cpu.c
@@ -51,13 +51,6 @@
51 51
52#include "clkc.h" 52#include "clkc.h"
53 53
54struct meson_clk_cpu {
55 struct notifier_block clk_nb;
56 const struct clk_div_table *div_table;
57 struct clk_hw hw;
58 void __iomem *base;
59 u16 reg_off;
60};
61#define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw) 54#define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw)
62#define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb) 55#define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb)
63 56
@@ -119,6 +112,7 @@ static unsigned long meson_clk_cpu_recalc_rate(struct clk_hw *hw,
119 return parent_rate / div; 112 return parent_rate / div;
120} 113}
121 114
115/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
122static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu, 116static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
123 struct clk_notifier_data *ndata) 117 struct clk_notifier_data *ndata)
124{ 118{
@@ -140,6 +134,7 @@ static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
140 return 0; 134 return 0;
141} 135}
142 136
137/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
143static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu, 138static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
144 struct clk_notifier_data *ndata) 139 struct clk_notifier_data *ndata)
145{ 140{
@@ -161,7 +156,7 @@ static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
161 * PLL clock is to be changed. We use the xtal input as temporary parent 156 * PLL clock is to be changed. We use the xtal input as temporary parent
162 * while the PLL frequency is stabilized. 157 * while the PLL frequency is stabilized.
163 */ 158 */
164static int meson_clk_cpu_notifier_cb(struct notifier_block *nb, 159int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
165 unsigned long event, void *data) 160 unsigned long event, void *data)
166{ 161{
167 struct clk_notifier_data *ndata = data; 162 struct clk_notifier_data *ndata = data;
@@ -176,68 +171,8 @@ static int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
176 return notifier_from_errno(ret); 171 return notifier_from_errno(ret);
177} 172}
178 173
179static const struct clk_ops meson_clk_cpu_ops = { 174const struct clk_ops meson_clk_cpu_ops = {
180 .recalc_rate = meson_clk_cpu_recalc_rate, 175 .recalc_rate = meson_clk_cpu_recalc_rate,
181 .round_rate = meson_clk_cpu_round_rate, 176 .round_rate = meson_clk_cpu_round_rate,
182 .set_rate = meson_clk_cpu_set_rate, 177 .set_rate = meson_clk_cpu_set_rate,
183}; 178};
184
185struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
186 void __iomem *reg_base,
187 spinlock_t *lock)
188{
189 struct clk *clk;
190 struct clk *pclk;
191 struct meson_clk_cpu *clk_cpu;
192 struct clk_init_data init;
193 int ret;
194
195 clk_cpu = kzalloc(sizeof(*clk_cpu), GFP_KERNEL);
196 if (!clk_cpu)
197 return ERR_PTR(-ENOMEM);
198
199 clk_cpu->base = reg_base;
200 clk_cpu->reg_off = clk_conf->reg_off;
201 clk_cpu->div_table = clk_conf->conf.div_table;
202 clk_cpu->clk_nb.notifier_call = meson_clk_cpu_notifier_cb;
203
204 init.name = clk_conf->clk_name;
205 init.ops = &meson_clk_cpu_ops;
206 init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE;
207 init.flags |= CLK_SET_RATE_PARENT;
208 init.parent_names = clk_conf->clks_parent;
209 init.num_parents = 1;
210
211 clk_cpu->hw.init = &init;
212
213 pclk = __clk_lookup(clk_conf->clks_parent[0]);
214 if (!pclk) {
215 pr_err("%s: could not lookup parent clock %s\n",
216 __func__, clk_conf->clks_parent[0]);
217 ret = -EINVAL;
218 goto free_clk;
219 }
220
221 ret = clk_notifier_register(pclk, &clk_cpu->clk_nb);
222 if (ret) {
223 pr_err("%s: failed to register clock notifier for %s\n",
224 __func__, clk_conf->clk_name);
225 goto free_clk;
226 }
227
228 clk = clk_register(NULL, &clk_cpu->hw);
229 if (IS_ERR(clk)) {
230 ret = PTR_ERR(clk);
231 goto unregister_clk_nb;
232 }
233
234 return clk;
235
236unregister_clk_nb:
237 clk_notifier_unregister(pclk, &clk_cpu->clk_nb);
238free_clk:
239 kfree(clk_cpu);
240
241 return ERR_PTR(ret);
242}
243