Commit 176d1169 authored by Masahiro Yamada's avatar Masahiro Yamada Committed by Stephen Boyd

clk: move core->parents allocation to clk_register()

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: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: default avatarVladimir Zapolskiy <vz@mleia.com>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
parent 3a6e8454
...@@ -1067,13 +1067,6 @@ static int clk_fetch_parent_index(struct clk_core *core, ...@@ -1067,13 +1067,6 @@ static int clk_fetch_parent_index(struct clk_core *core,
{ {
int i; 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, * find index of new parent clock using cached parent ptrs,
* or if not yet cached, use string name comparison and cache * 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) ...@@ -1718,11 +1711,6 @@ static struct clk_core *__clk_init_parent(struct clk_core *core)
index = core->ops->get_parent(core->hw); 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); ret = clk_core_get_parent_by_index(core, index);
out: out:
...@@ -2361,26 +2349,15 @@ static int __clk_core_init(struct clk_core *core) ...@@ -2361,26 +2349,15 @@ static int __clk_core_init(struct clk_core *core)
__func__, core->name); __func__, core->name);
/* /*
* Allocate an array of struct clk *'s to avoid unnecessary string * clk_core_lookup returns NULL for parents that have not been
* look-ups of clk's possible parents. This can fail for clocks passed * clk_init'd; thus any access to clk->parents[] must check
* in to clk_init during early boot; thus any access to core->parents[] * for a NULL pointer. We can always perform lazy lookups for
* must always check for a NULL pointer and try to populate it if * missing parents later on.
* necessary.
*/ */
if (core->num_parents > 1) { if (core->parents)
core->parents = kcalloc(core->num_parents, for (i = 0; i < core->num_parents; i++)
sizeof(*core->parents), GFP_KERNEL); core->parents[i] =
/* clk_core_lookup(core->parent_names[i]);
* 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]);
}
core->parent = __clk_init_parent(core); core->parent = __clk_init_parent(core);
...@@ -2578,12 +2555,20 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) ...@@ -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); INIT_HLIST_HEAD(&core->clks);
hw->clk = __clk_create_clk(hw, NULL, NULL); hw->clk = __clk_create_clk(hw, NULL, NULL);
if (IS_ERR(hw->clk)) { if (IS_ERR(hw->clk)) {
ret = PTR_ERR(hw->clk); ret = PTR_ERR(hw->clk);
goto fail_parent_names_copy; goto fail_parents;
} }
ret = __clk_core_init(core); ret = __clk_core_init(core);
...@@ -2593,6 +2578,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) ...@@ -2593,6 +2578,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
__clk_free_clk(hw->clk); __clk_free_clk(hw->clk);
hw->clk = NULL; hw->clk = NULL;
fail_parents:
kfree(core->parents);
fail_parent_names_copy: fail_parent_names_copy:
while (--i >= 0) while (--i >= 0)
kfree_const(core->parent_names[i]); kfree_const(core->parent_names[i]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment