From: Magnus Damm <[email protected]>

This patch hacks the CCF core to take clock-indices into
consideration when making a default clock name in case
clock-output-names is not provided.

Without this patch of_clk_get_parent_name() does not work
for clocks with multiple indices associated with one node.

Proof of concept only. Leaks memory. Not for upstream merge.

Not-Yet-Signed-off-by: Magnus Damm <[email protected]>
---

 Written on top of "renesas-drivers-2015-09-08-v4.2"
 Needed to propagate clock frequencies from CPG to MSTP.

 drivers/clk/clk.c                    |   46 ++++++++++++++++++++++------------
 drivers/clk/shmobile/clk-mstp.c      |    3 --
 drivers/clk/shmobile/clk-rcar-gen3.c |   13 +--------
 include/linux/clk-provider.h         |    1 
 4 files changed, 35 insertions(+), 28 deletions(-)

--- 0001/drivers/clk/clk.c
+++ work/drivers/clk/clk.c      2015-09-09 13:48:21.992366518 +0900
@@ -3045,31 +3045,25 @@ int of_clk_get_parent_count(struct devic
 }
 EXPORT_SYMBOL_GPL(of_clk_get_parent_count);
 
-const char *of_clk_get_parent_name(struct device_node *np, int index)
+const char *of_clk_get_name(struct device_node *np, int index)
 {
-       struct of_phandle_args clkspec;
        struct property *prop;
        const char *clk_name;
        const __be32 *vp;
        u32 pv;
-       int rc;
        int count;
+       bool has_indices = false;
 
        if (index < 0)
                return NULL;
 
-       rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
-                                       &clkspec);
-       if (rc)
-               return NULL;
-
-       index = clkspec.args_count ? clkspec.args[0] : 0;
        count = 0;
 
        /* if there is an indices property, use it to transfer the index
         * specified into an array offset for the clock-output-names property.
         */
-       of_property_for_each_u32(clkspec.np, "clock-indices", prop, vp, pv) {
+       of_property_for_each_u32(np, "clock-indices", prop, vp, pv) {
+               has_indices = true;
                if (index == pv) {
                        index = count;
                        break;
@@ -3077,12 +3071,34 @@ const char *of_clk_get_parent_name(struc
                count++;
        }
 
-       if (of_property_read_string_index(clkspec.np, "clock-output-names",
-                                         index,
-                                         &clk_name) < 0)
-               clk_name = clkspec.np->name;
+       if (of_property_read_string_index(np, "clock-output-names", index,
+                                         &clk_name) < 0) {
+               if (has_indices)
+                       return kasprintf(GFP_KERNEL, "%s.%u", np->name, index);
+               else
+                       return kstrdup_const(np->name, GFP_KERNEL);
+       }
 
-       of_node_put(clkspec.np);
+       return kstrdup_const(clk_name, GFP_KERNEL);
+}
+EXPORT_SYMBOL_GPL(of_clk_get_name);
+
+const char *of_clk_get_parent_name(struct device_node *np, int index)
+{
+       struct of_phandle_args clkspec;
+       const char *clk_name = NULL;
+       int rc;
+
+       if (index < 0)
+               return NULL;
+
+       rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
+                                       &clkspec);
+       if (!rc) {
+               clk_name = of_clk_get_name(clkspec.np, clkspec.args_count ?
+                                          clkspec.args[0] : 0);
+               of_node_put(clkspec.np);
+       }
        return clk_name;
 }
 EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
--- 0001/drivers/clk/shmobile/clk-mstp.c
+++ work/drivers/clk/shmobile/clk-mstp.c        2015-09-09 13:45:51.652366518 
+0900
@@ -216,8 +216,7 @@ static void __init cpg_mstp_clocks_init(
 
                if (of_property_read_string_index(np, "clock-output-names",
                                                  i, &name) < 0)
-                       allocated_name = name = kasprintf(GFP_KERNEL, "%s.%u",
-                                                          np->name, clkidx);
+                       allocated_name = name = of_clk_get_name(np, clkidx);
 
                clks[clkidx] = cpg_mstp_clock_register(name, parent_name,
                                                       clkidx, group);
--- 0001/drivers/clk/shmobile/clk-rcar-gen3.c
+++ work/drivers/clk/shmobile/clk-rcar-gen3.c   2015-09-09 13:45:51.652366518 
+0900
@@ -28,15 +28,6 @@
 #define RCAR_GEN3_CLK_PLL4     5
 #define RCAR_GEN3_CLK_NR       6
 
-static const char * const rcar_gen3_clk_names[RCAR_GEN3_CLK_NR] = {
-       [RCAR_GEN3_CLK_MAIN] = "main",
-       [RCAR_GEN3_CLK_PLL0] = "pll0",
-       [RCAR_GEN3_CLK_PLL1] = "pll1",
-       [RCAR_GEN3_CLK_PLL2] = "pll2",
-       [RCAR_GEN3_CLK_PLL3] = "pll3",
-       [RCAR_GEN3_CLK_PLL4] = "pll4",
-};
-
 struct rcar_gen3_cpg {
        struct clk_onecell_data data;
        void __iomem *reg;
@@ -116,7 +107,7 @@ rcar_gen3_cpg_register_clk(struct device
                           const struct cpg_pll_config *config,
                           unsigned int gen3_clk)
 {
-       const char *parent_name = rcar_gen3_clk_names[RCAR_GEN3_CLK_MAIN];
+       const char *parent_name = of_clk_get_name(np, RCAR_GEN3_CLK_MAIN);
        unsigned int mult = 1;
        unsigned int div = 1;
        u32 value;
@@ -157,7 +148,7 @@ rcar_gen3_cpg_register_clk(struct device
                return ERR_PTR(-EINVAL);
        }
 
-       return clk_register_fixed_factor(NULL, rcar_gen3_clk_names[gen3_clk],
+       return clk_register_fixed_factor(NULL, of_clk_get_name(np, gen3_clk),
                                         parent_name, 0, mult, div);
 }
 
--- 0001/include/linux/clk-provider.h
+++ work/include/linux/clk-provider.h   2015-09-09 13:46:21.052366518 +0900
@@ -665,6 +665,7 @@ struct clk *of_clk_src_onecell_get(struc
 int of_clk_get_parent_count(struct device_node *np);
 int of_clk_parent_fill(struct device_node *np, const char **parents,
                       unsigned int size);
+const char *of_clk_get_name(struct device_node *np, int index);
 const char *of_clk_get_parent_name(struct device_node *np, int index);
 
 void of_clk_init(const struct of_device_id *matches);
--
To unsubscribe from this list: send the line "unsubscribe linux-clk" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to