diff options
Diffstat (limited to 'drivers/clk/meson/clk-cpu.c')
-rw-r--r-- | drivers/clk/meson/clk-cpu.c | 73 |
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 | ||
54 | struct 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 */ | ||
122 | static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu, | 116 | static 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 */ | ||
143 | static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu, | 138 | static 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 | */ |
164 | static int meson_clk_cpu_notifier_cb(struct notifier_block *nb, | 159 | int 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 | ||
179 | static const struct clk_ops meson_clk_cpu_ops = { | 174 | const 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 | |||
185 | struct 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 | |||
236 | unregister_clk_nb: | ||
237 | clk_notifier_unregister(pclk, &clk_cpu->clk_nb); | ||
238 | free_clk: | ||
239 | kfree(clk_cpu); | ||
240 | |||
241 | return ERR_PTR(ret); | ||
242 | } | ||
243 | |||