mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	clk: Add devm_of_clk_add_hw_provider()/del_provider() APIs
Sometimes we only have one of_clk_del_provider() call in driver error and remove paths, because we're missing a devm_of_clk_add_hw_provider() API. Introduce the API so we can convert drivers to use this and potentially reduce the amount of code needed to remove providers in drivers. Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
This commit is contained in:
		
							parent
							
								
									2bd6bf03f4
								
							
						
					
					
						commit
						aa795c41d9
					
				
					 3 changed files with 66 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -237,6 +237,7 @@ CLOCK
 | 
			
		|||
  devm_clk_get()
 | 
			
		||||
  devm_clk_put()
 | 
			
		||||
  devm_clk_hw_register()
 | 
			
		||||
  devm_of_clk_add_hw_provider()
 | 
			
		||||
 | 
			
		||||
DMA
 | 
			
		||||
  dmam_alloc_coherent()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3177,6 +3177,37 @@ int of_clk_add_hw_provider(struct device_node *np,
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(of_clk_add_hw_provider);
 | 
			
		||||
 | 
			
		||||
static void devm_of_clk_release_provider(struct device *dev, void *res)
 | 
			
		||||
{
 | 
			
		||||
	of_clk_del_provider(*(struct device_node **)res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int devm_of_clk_add_hw_provider(struct device *dev,
 | 
			
		||||
			struct clk_hw *(*get)(struct of_phandle_args *clkspec,
 | 
			
		||||
					      void *data),
 | 
			
		||||
			void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct device_node **ptr, *np;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	ptr = devres_alloc(devm_of_clk_release_provider, sizeof(*ptr),
 | 
			
		||||
			   GFP_KERNEL);
 | 
			
		||||
	if (!ptr)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	np = dev->of_node;
 | 
			
		||||
	ret = of_clk_add_hw_provider(np, get, data);
 | 
			
		||||
	if (!ret) {
 | 
			
		||||
		*ptr = np;
 | 
			
		||||
		devres_add(dev, ptr);
 | 
			
		||||
	} else {
 | 
			
		||||
		devres_free(ptr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(devm_of_clk_add_hw_provider);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * of_clk_del_provider() - Remove a previously registered clock provider
 | 
			
		||||
 * @np: Device node pointer associated with clock provider
 | 
			
		||||
| 
						 | 
				
			
			@ -3198,6 +3229,27 @@ void of_clk_del_provider(struct device_node *np)
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(of_clk_del_provider);
 | 
			
		||||
 | 
			
		||||
static int devm_clk_provider_match(struct device *dev, void *res, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct device_node **np = res;
 | 
			
		||||
 | 
			
		||||
	if (WARN_ON(!np || !*np))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return *np == data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void devm_of_clk_del_provider(struct device *dev)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	ret = devres_release(dev, devm_of_clk_release_provider,
 | 
			
		||||
			     devm_clk_provider_match, dev->of_node);
 | 
			
		||||
 | 
			
		||||
	WARN_ON(ret);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(devm_of_clk_del_provider);
 | 
			
		||||
 | 
			
		||||
static struct clk_hw *
 | 
			
		||||
__of_clk_get_hw_from_provider(struct of_clk_provider *provider,
 | 
			
		||||
			      struct of_phandle_args *clkspec)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -815,7 +815,12 @@ int of_clk_add_hw_provider(struct device_node *np,
 | 
			
		|||
			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
 | 
			
		||||
						 void *data),
 | 
			
		||||
			   void *data);
 | 
			
		||||
int devm_of_clk_add_hw_provider(struct device *dev,
 | 
			
		||||
			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
 | 
			
		||||
						 void *data),
 | 
			
		||||
			   void *data);
 | 
			
		||||
void of_clk_del_provider(struct device_node *np);
 | 
			
		||||
void devm_of_clk_del_provider(struct device *dev);
 | 
			
		||||
struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
 | 
			
		||||
				  void *data);
 | 
			
		||||
struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec,
 | 
			
		||||
| 
						 | 
				
			
			@ -847,7 +852,15 @@ static inline int of_clk_add_hw_provider(struct device_node *np,
 | 
			
		|||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
static inline int devm_of_clk_add_hw_provider(struct device *dev,
 | 
			
		||||
			   struct clk_hw *(*get)(struct of_phandle_args *clkspec,
 | 
			
		||||
						 void *data),
 | 
			
		||||
			   void *data)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
static inline void of_clk_del_provider(struct device_node *np) {}
 | 
			
		||||
static inline void devm_of_clk_del_provider(struct device *dev) {}
 | 
			
		||||
static inline struct clk *of_clk_src_simple_get(
 | 
			
		||||
	struct of_phandle_args *clkspec, void *data)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue