forked from mirrors/linux
		
	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:
		
							parent
							
								
									8005c49d9a
								
							
						
					
					
						commit
						f66541ba02
					
				
					 1 changed files with 17 additions and 16 deletions
				
			
		| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue