clk: ti: add support for clkctrl aliases
authorTero Kristo <t-kristo@ti.com>
Tue, 26 Sep 2017 12:34:27 +0000 (15:34 +0300)
committerTero Kristo <t-kristo@ti.com>
Fri, 1 Dec 2017 13:15:20 +0000 (15:15 +0200)
hwmod core still depends on certain clocks being found by name, so we
need to add support for adding clkctrl clock aliases. This patch can
be reverted when no longer needed by hwmod core code.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
drivers/clk/ti/clk.c

index e5a1c8297a1d256fd1d6fc006121b97a6d89e821..10a7045408badd006ec6b698c35be251cef9f4ba 100644 (file)
@@ -108,18 +108,70 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
        struct device_node *node;
        struct clk *clk;
        struct of_phandle_args clkspec;
+       char buf[64];
+       char *ptr;
+       char *tags[2];
+       int i;
+       int num_args;
+       int ret;
+       static bool clkctrl_nodes_missing;
+       static bool has_clkctrl_data;
 
        for (c = oclks; c->node_name != NULL; c++) {
-               node = of_find_node_by_name(NULL, c->node_name);
+               strcpy(buf, c->node_name);
+               ptr = buf;
+               for (i = 0; i < 2; i++)
+                       tags[i] = NULL;
+               num_args = 0;
+               while (*ptr) {
+                       if (*ptr == ':') {
+                               if (num_args >= 2) {
+                                       pr_warn("Bad number of tags on %s\n",
+                                               c->node_name);
+                                       return;
+                               }
+                               tags[num_args++] = ptr + 1;
+                               *ptr = 0;
+                       }
+                       ptr++;
+               }
+
+               if (num_args && clkctrl_nodes_missing)
+                       continue;
+
+               node = of_find_node_by_name(NULL, buf);
+               if (num_args)
+                       node = of_find_node_by_name(node, "clk");
                clkspec.np = node;
+               clkspec.args_count = num_args;
+               for (i = 0; i < num_args; i++) {
+                       ret = kstrtoint(tags[i], i ? 10 : 16, clkspec.args + i);
+                       if (ret) {
+                               pr_warn("Bad tag in %s at %d: %s\n",
+                                       c->node_name, i, tags[i]);
+                               return;
+                       }
+               }
                clk = of_clk_get_from_provider(&clkspec);
 
                if (!IS_ERR(clk)) {
                        c->lk.clk = clk;
                        clkdev_add(&c->lk);
                } else {
-                       pr_warn("failed to lookup clock node %s\n",
-                               c->node_name);
+                       if (num_args && !has_clkctrl_data) {
+                               if (of_find_compatible_node(NULL, NULL,
+                                                           "ti,clkctrl")) {
+                                       has_clkctrl_data = true;
+                               } else {
+                                       clkctrl_nodes_missing = true;
+
+                                       pr_warn("missing clkctrl nodes, please update your dts.\n");
+                                       continue;
+                               }
+                       }
+
+                       pr_warn("failed to lookup clock node %s, ret=%ld\n",
+                               c->node_name, PTR_ERR(clk));
                }
        }
 }