|
@@ -22,6 +22,8 @@
|
|
|
#include <linux/of_address.h>
|
|
|
#include <linux/list.h>
|
|
|
|
|
|
+#include "clock.h"
|
|
|
+
|
|
|
#undef pr_fmt
|
|
|
#define pr_fmt(fmt) "%s: " fmt, __func__
|
|
|
|
|
@@ -183,3 +185,111 @@ void ti_dt_clk_init_retry_clks(void)
|
|
|
retries--;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+void __init ti_clk_patch_legacy_clks(struct ti_clk **patch)
|
|
|
+{
|
|
|
+ while (*patch) {
|
|
|
+ memcpy((*patch)->patch, *patch, sizeof(**patch));
|
|
|
+ patch++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+struct clk __init *ti_clk_register_clk(struct ti_clk *setup)
|
|
|
+{
|
|
|
+ struct clk *clk;
|
|
|
+ struct ti_clk_fixed *fixed;
|
|
|
+ struct ti_clk_fixed_factor *fixed_factor;
|
|
|
+ struct clk_hw *clk_hw;
|
|
|
+
|
|
|
+ if (setup->clk)
|
|
|
+ return setup->clk;
|
|
|
+
|
|
|
+ switch (setup->type) {
|
|
|
+ case TI_CLK_FIXED:
|
|
|
+ fixed = setup->data;
|
|
|
+
|
|
|
+ clk = clk_register_fixed_rate(NULL, setup->name, NULL,
|
|
|
+ CLK_IS_ROOT, fixed->frequency);
|
|
|
+ break;
|
|
|
+ case TI_CLK_FIXED_FACTOR:
|
|
|
+ fixed_factor = setup->data;
|
|
|
+
|
|
|
+ clk = clk_register_fixed_factor(NULL, setup->name,
|
|
|
+ fixed_factor->parent,
|
|
|
+ 0, fixed_factor->mult,
|
|
|
+ fixed_factor->div);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ pr_err("bad type for %s!\n", setup->name);
|
|
|
+ clk = ERR_PTR(-EINVAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!IS_ERR(clk)) {
|
|
|
+ setup->clk = clk;
|
|
|
+ if (setup->clkdm_name) {
|
|
|
+ if (__clk_get_flags(clk) & CLK_IS_BASIC) {
|
|
|
+ pr_warn("can't setup clkdm for basic clk %s\n",
|
|
|
+ setup->name);
|
|
|
+ } else {
|
|
|
+ clk_hw = __clk_get_hw(clk);
|
|
|
+ to_clk_hw_omap(clk_hw)->clkdm_name =
|
|
|
+ setup->clkdm_name;
|
|
|
+ omap2_init_clk_clkdm(clk_hw);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return clk;
|
|
|
+}
|
|
|
+
|
|
|
+int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks)
|
|
|
+{
|
|
|
+ struct clk *clk;
|
|
|
+ bool retry;
|
|
|
+ struct ti_clk_alias *retry_clk;
|
|
|
+ struct ti_clk_alias *tmp;
|
|
|
+
|
|
|
+ while (clks->clk) {
|
|
|
+ clk = ti_clk_register_clk(clks->clk);
|
|
|
+ if (IS_ERR(clk)) {
|
|
|
+ if (PTR_ERR(clk) == -EAGAIN) {
|
|
|
+ list_add(&clks->link, &retry_list);
|
|
|
+ } else {
|
|
|
+ pr_err("register for %s failed: %ld\n",
|
|
|
+ clks->clk->name, PTR_ERR(clk));
|
|
|
+ return PTR_ERR(clk);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ clks->lk.clk = clk;
|
|
|
+ clkdev_add(&clks->lk);
|
|
|
+ }
|
|
|
+ clks++;
|
|
|
+ }
|
|
|
+
|
|
|
+ retry = true;
|
|
|
+
|
|
|
+ while (!list_empty(&retry_list) && retry) {
|
|
|
+ retry = false;
|
|
|
+ list_for_each_entry_safe(retry_clk, tmp, &retry_list, link) {
|
|
|
+ pr_debug("retry-init: %s\n", retry_clk->clk->name);
|
|
|
+ clk = ti_clk_register_clk(retry_clk->clk);
|
|
|
+ if (IS_ERR(clk)) {
|
|
|
+ if (PTR_ERR(clk) == -EAGAIN) {
|
|
|
+ continue;
|
|
|
+ } else {
|
|
|
+ pr_err("register for %s failed: %ld\n",
|
|
|
+ retry_clk->clk->name,
|
|
|
+ PTR_ERR(clk));
|
|
|
+ return PTR_ERR(clk);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ retry = true;
|
|
|
+ retry_clk->lk.clk = clk;
|
|
|
+ clkdev_add(&retry_clk->lk);
|
|
|
+ list_del(&retry_clk->link);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|