diff options
Diffstat (limited to 'drivers/clk/ti/clk.c')
-rw-r--r-- | drivers/clk/ti/clk.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index 337abe5909e1..e22b95646e09 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <linux/of_address.h> | 22 | #include <linux/of_address.h> |
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | 24 | ||
25 | #include "clock.h" | ||
26 | |||
25 | #undef pr_fmt | 27 | #undef pr_fmt |
26 | #define pr_fmt(fmt) "%s: " fmt, __func__ | 28 | #define pr_fmt(fmt) "%s: " fmt, __func__ |
27 | 29 | ||
@@ -183,3 +185,128 @@ void ti_dt_clk_init_retry_clks(void) | |||
183 | retries--; | 185 | retries--; |
184 | } | 186 | } |
185 | } | 187 | } |
188 | |||
189 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_ATAGS) | ||
190 | void __init ti_clk_patch_legacy_clks(struct ti_clk **patch) | ||
191 | { | ||
192 | while (*patch) { | ||
193 | memcpy((*patch)->patch, *patch, sizeof(**patch)); | ||
194 | patch++; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | struct clk __init *ti_clk_register_clk(struct ti_clk *setup) | ||
199 | { | ||
200 | struct clk *clk; | ||
201 | struct ti_clk_fixed *fixed; | ||
202 | struct ti_clk_fixed_factor *fixed_factor; | ||
203 | struct clk_hw *clk_hw; | ||
204 | |||
205 | if (setup->clk) | ||
206 | return setup->clk; | ||
207 | |||
208 | switch (setup->type) { | ||
209 | case TI_CLK_FIXED: | ||
210 | fixed = setup->data; | ||
211 | |||
212 | clk = clk_register_fixed_rate(NULL, setup->name, NULL, | ||
213 | CLK_IS_ROOT, fixed->frequency); | ||
214 | break; | ||
215 | case TI_CLK_MUX: | ||
216 | clk = ti_clk_register_mux(setup); | ||
217 | break; | ||
218 | case TI_CLK_DIVIDER: | ||
219 | clk = ti_clk_register_divider(setup); | ||
220 | break; | ||
221 | case TI_CLK_COMPOSITE: | ||
222 | clk = ti_clk_register_composite(setup); | ||
223 | break; | ||
224 | case TI_CLK_FIXED_FACTOR: | ||
225 | fixed_factor = setup->data; | ||
226 | |||
227 | clk = clk_register_fixed_factor(NULL, setup->name, | ||
228 | fixed_factor->parent, | ||
229 | 0, fixed_factor->mult, | ||
230 | fixed_factor->div); | ||
231 | break; | ||
232 | case TI_CLK_GATE: | ||
233 | clk = ti_clk_register_gate(setup); | ||
234 | break; | ||
235 | case TI_CLK_DPLL: | ||
236 | clk = ti_clk_register_dpll(setup); | ||
237 | break; | ||
238 | default: | ||
239 | pr_err("bad type for %s!\n", setup->name); | ||
240 | clk = ERR_PTR(-EINVAL); | ||
241 | } | ||
242 | |||
243 | if (!IS_ERR(clk)) { | ||
244 | setup->clk = clk; | ||
245 | if (setup->clkdm_name) { | ||
246 | if (__clk_get_flags(clk) & CLK_IS_BASIC) { | ||
247 | pr_warn("can't setup clkdm for basic clk %s\n", | ||
248 | setup->name); | ||
249 | } else { | ||
250 | clk_hw = __clk_get_hw(clk); | ||
251 | to_clk_hw_omap(clk_hw)->clkdm_name = | ||
252 | setup->clkdm_name; | ||
253 | omap2_init_clk_clkdm(clk_hw); | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | |||
258 | return clk; | ||
259 | } | ||
260 | |||
261 | int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks) | ||
262 | { | ||
263 | struct clk *clk; | ||
264 | bool retry; | ||
265 | struct ti_clk_alias *retry_clk; | ||
266 | struct ti_clk_alias *tmp; | ||
267 | |||
268 | while (clks->clk) { | ||
269 | clk = ti_clk_register_clk(clks->clk); | ||
270 | if (IS_ERR(clk)) { | ||
271 | if (PTR_ERR(clk) == -EAGAIN) { | ||
272 | list_add(&clks->link, &retry_list); | ||
273 | } else { | ||
274 | pr_err("register for %s failed: %ld\n", | ||
275 | clks->clk->name, PTR_ERR(clk)); | ||
276 | return PTR_ERR(clk); | ||
277 | } | ||
278 | } else { | ||
279 | clks->lk.clk = clk; | ||
280 | clkdev_add(&clks->lk); | ||
281 | } | ||
282 | clks++; | ||
283 | } | ||
284 | |||
285 | retry = true; | ||
286 | |||
287 | while (!list_empty(&retry_list) && retry) { | ||
288 | retry = false; | ||
289 | list_for_each_entry_safe(retry_clk, tmp, &retry_list, link) { | ||
290 | pr_debug("retry-init: %s\n", retry_clk->clk->name); | ||
291 | clk = ti_clk_register_clk(retry_clk->clk); | ||
292 | if (IS_ERR(clk)) { | ||
293 | if (PTR_ERR(clk) == -EAGAIN) { | ||
294 | continue; | ||
295 | } else { | ||
296 | pr_err("register for %s failed: %ld\n", | ||
297 | retry_clk->clk->name, | ||
298 | PTR_ERR(clk)); | ||
299 | return PTR_ERR(clk); | ||
300 | } | ||
301 | } else { | ||
302 | retry = true; | ||
303 | retry_clk->lk.clk = clk; | ||
304 | clkdev_add(&retry_clk->lk); | ||
305 | list_del(&retry_clk->link); | ||
306 | } | ||
307 | } | ||
308 | } | ||
309 | |||
310 | return 0; | ||
311 | } | ||
312 | #endif | ||