aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/ti/clk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/ti/clk.c')
-rw-r--r--drivers/clk/ti/clk.c127
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)
190void __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
198struct 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
261int __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