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: 0a4807c2f9
("clk: Make of_clk_get_parent_name() robust with #clock-cells = 1")
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
This commit is contained in:
Родитель
8005c49d9a
Коммит
f66541ba02
|
@ -209,6 +209,8 @@ EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
|
||||||
|
|
||||||
struct clk_gpio_delayed_register_data {
|
struct clk_gpio_delayed_register_data {
|
||||||
const char *gpio_name;
|
const char *gpio_name;
|
||||||
|
int num_parents;
|
||||||
|
const char **parent_names;
|
||||||
struct device_node *node;
|
struct device_node *node;
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
struct clk *clk;
|
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_gpio_delayed_register_data *data = _data;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
const char **parent_names;
|
|
||||||
int i, num_parents;
|
|
||||||
int gpio;
|
int gpio;
|
||||||
enum of_gpio_flags of_flags;
|
enum of_gpio_flags of_flags;
|
||||||
|
|
||||||
|
@ -248,26 +248,14 @@ static struct clk *of_clk_gpio_delayed_register_get(
|
||||||
return ERR_PTR(gpio);
|
return ERR_PTR(gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
num_parents = of_clk_get_parent_count(data->node);
|
clk = data->clk_register_get(data->node->name, data->parent_names,
|
||||||
|
data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW);
|
||||||
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);
|
|
||||||
if (IS_ERR(clk))
|
if (IS_ERR(clk))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
data->clk = clk;
|
data->clk = clk;
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&data->lock);
|
mutex_unlock(&data->lock);
|
||||||
kfree(parent_names);
|
|
||||||
|
|
||||||
return clk;
|
return clk;
|
||||||
}
|
}
|
||||||
|
@ -296,11 +284,24 @@ static void __init of_gpio_clk_setup(struct device_node *node,
|
||||||
unsigned gpio, bool active_low))
|
unsigned gpio, bool active_low))
|
||||||
{
|
{
|
||||||
struct clk_gpio_delayed_register_data *data;
|
struct clk_gpio_delayed_register_data *data;
|
||||||
|
const char **parent_names;
|
||||||
|
int i, num_parents;
|
||||||
|
|
||||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||||
if (!data)
|
if (!data)
|
||||||
return;
|
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->node = node;
|
||||||
data->gpio_name = gpio_name;
|
data->gpio_name = gpio_name;
|
||||||
data->clk_register_get = clk_register_get;
|
data->clk_register_get = clk_register_get;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче