clk: move core->parents allocation to clk_register()
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Mon, 28 Dec 2015 10:23:00 +0000 (19:23 +0900)
committerStephen Boyd <sboyd@codeaurora.org>
Tue, 2 Feb 2016 01:01:46 +0000 (17:01 -0800)
Currently, __clk_core_init() allows failure of the kcalloc() for the
core->parents.  So, clk_fetch_parent_index() and __clk_init_parent()
also try to allocate core->parents in case it has not been allocated
yet.  Scattering memory allocation here and there makes things
complicated.

Like other clk_core members, allocate core->parents in clk_register()
and let it fail in case of memory shortage.  If we cannot allocate
such a small piece of memory, the system is already insane.  There is
no point to postpone the memory allocation.

Also, allocate core->parents regardless of core->num_parents.  We want
it even if core->num_parents == 1 because clk_fetch_parent_index()
might be called against the clk_core with a single parent.

If core->num_parents == 0, core->parents is set to ZERO_SIZE_PTR. It
is harmless because no access happens to core->parents in such a case.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
drivers/clk/clk.c

index f9cab0919bb49728015956ddc37e3049b9e2d01a..a92feedda592bff71240780ec43d7cb2c9382b50 100644 (file)
@@ -1067,13 +1067,6 @@ static int clk_fetch_parent_index(struct clk_core *core,
 {
        int i;
 
-       if (!core->parents) {
-               core->parents = kcalloc(core->num_parents,
-                                       sizeof(*core->parents), GFP_KERNEL);
-               if (!core->parents)
-                       return -ENOMEM;
-       }
-
        /*
         * find index of new parent clock using cached parent ptrs,
         * or if not yet cached, use string name comparison and cache
@@ -1718,11 +1711,6 @@ static struct clk_core *__clk_init_parent(struct clk_core *core)
 
        index = core->ops->get_parent(core->hw);
 
-       if (!core->parents)
-               core->parents =
-                       kcalloc(core->num_parents, sizeof(*core->parents),
-                                       GFP_KERNEL);
-
        ret = clk_core_get_parent_by_index(core, index);
 
 out:
@@ -2361,26 +2349,15 @@ static int __clk_core_init(struct clk_core *core)
                                __func__, core->name);
 
        /*
-        * Allocate an array of struct clk *'s to avoid unnecessary string
-        * look-ups of clk's possible parents.  This can fail for clocks passed
-        * in to clk_init during early boot; thus any access to core->parents[]
-        * must always check for a NULL pointer and try to populate it if
-        * necessary.
+        * clk_core_lookup returns NULL for parents that have not been
+        * clk_init'd; thus any access to clk->parents[] must check
+        * for a NULL pointer.  We can always perform lazy lookups for
+        * missing parents later on.
         */
-       if (core->num_parents > 1) {
-               core->parents = kcalloc(core->num_parents,
-                                       sizeof(*core->parents), GFP_KERNEL);
-               /*
-                * clk_core_lookup returns NULL for parents that have not been
-                * clk_init'd; thus any access to clk->parents[] must check
-                * for a NULL pointer.  We can always perform lazy lookups for
-                * missing parents later on.
-                */
-               if (core->parents)
-                       for (i = 0; i < core->num_parents; i++)
-                               core->parents[i] =
-                                       clk_core_lookup(core->parent_names[i]);
-       }
+       if (core->parents)
+               for (i = 0; i < core->num_parents; i++)
+                       core->parents[i] =
+                               clk_core_lookup(core->parent_names[i]);
 
        core->parent = __clk_init_parent(core);
 
@@ -2578,12 +2555,20 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
                }
        }
 
+       /* avoid unnecessary string look-ups of clk_core's possible parents. */
+       core->parents = kcalloc(core->num_parents, sizeof(*core->parents),
+                               GFP_KERNEL);
+       if (!core->parents) {
+               ret = -ENOMEM;
+               goto fail_parents;
+       };
+
        INIT_HLIST_HEAD(&core->clks);
 
        hw->clk = __clk_create_clk(hw, NULL, NULL);
        if (IS_ERR(hw->clk)) {
                ret = PTR_ERR(hw->clk);
-               goto fail_parent_names_copy;
+               goto fail_parents;
        }
 
        ret = __clk_core_init(core);
@@ -2593,6 +2578,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
        __clk_free_clk(hw->clk);
        hw->clk = NULL;
 
+fail_parents:
+       kfree(core->parents);
 fail_parent_names_copy:
        while (--i >= 0)
                kfree_const(core->parent_names[i]);