diff options
author | Jyri Sarha <jsarha@ti.com> | 2015-11-17 09:56:44 (GMT) |
---|---|---|
committer | Stephen Boyd <sboyd@codeaurora.org> | 2015-11-19 01:19:01 (GMT) |
commit | f66541ba02d5cb619b84fa4c5b43b3bcc8764716 (patch) | |
tree | b2f88fa28311b430c044c49e15ca794720178e79 | |
parent | 8005c49d9aea74d382f474ce11afbbc7d7130bec (diff) | |
download | linux-f66541ba02d5cb619b84fa4c5b43b3bcc8764716.tar.xz |
clk: gpio: Get parent clk names in of_gpio_clk_setup()
Get parent clk names in of_gpio_clk_setup() and store the names
in struct clk_gpio_delayed_register_data instead of doing it from
the clk provider's get() callback. of_clk_get_parent_name() can't
be called in struct of_clk_provider's get() callback since it may
make a call to of_clk_get_from_provider() and this in turn tries
to recursively lock of_clk_mutex.
Signed-off-by: Jyri Sarha <jsarha@ti.com>
Cc: Sergej Sawazki <ce3a@gmx.de>
Fixes: 0a4807c2f9a4 ("clk: Make of_clk_get_parent_name() robust with #clock-cells = 1")
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-rw-r--r-- | drivers/clk/clk-gpio.c | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 10819e2..335322d 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -209,6 +209,8 @@ EXPORT_SYMBOL_GPL(clk_register_gpio_mux); struct clk_gpio_delayed_register_data { const char *gpio_name; + int num_parents; + const char **parent_names; struct device_node *node; struct mutex lock; struct clk *clk; @@ -222,8 +224,6 @@ static struct clk *of_clk_gpio_delayed_register_get( { struct clk_gpio_delayed_register_data *data = _data; struct clk *clk; - const char **parent_names; - int i, num_parents; int gpio; enum of_gpio_flags of_flags; @@ -248,26 +248,14 @@ static struct clk *of_clk_gpio_delayed_register_get( return ERR_PTR(gpio); } - num_parents = of_clk_get_parent_count(data->node); - - parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); - if (!parent_names) { - clk = ERR_PTR(-ENOMEM); - goto out; - } - - for (i = 0; i < num_parents; i++) - parent_names[i] = of_clk_get_parent_name(data->node, i); - - clk = data->clk_register_get(data->node->name, parent_names, - num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW); + clk = data->clk_register_get(data->node->name, data->parent_names, + data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW); if (IS_ERR(clk)) goto out; data->clk = clk; out: mutex_unlock(&data->lock); - kfree(parent_names); return clk; } @@ -296,11 +284,24 @@ static void __init of_gpio_clk_setup(struct device_node *node, unsigned gpio, bool active_low)) { struct clk_gpio_delayed_register_data *data; + const char **parent_names; + int i, num_parents; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) return; + num_parents = of_clk_get_parent_count(node); + + parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); + if (!parent_names) + return; + + for (i = 0; i < num_parents; i++) + parent_names[i] = of_clk_get_parent_name(node, i); + + data->num_parents = num_parents; + data->parent_names = parent_names; data->node = node; data->gpio_name = gpio_name; data->clk_register_get = clk_register_get; |