clk: fixed: add devm helper for clk_hw_register_fixed_factor()
Add a devm helper for clk_hw_register_fixed_factor() so that drivers that internally register fixed factor clocks for things like dividers don't need to manually unregister them on remove or if probe fails. Signed-off-by: Daniel Palmer <daniel@0x0f.com> Link: https://lore.kernel.org/r/20210211052206.2955988-4-daniel@0x0f.com Signed-off-by: Stephen Boyd <sboyd@kernel.org>
This commit is contained in:
parent
4f83b5233f
commit
0b9266d295
@ -64,10 +64,16 @@ const struct clk_ops clk_fixed_factor_ops = {
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
|
||||
|
||||
static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void *res)
|
||||
{
|
||||
clk_hw_unregister_fixed_factor(&((struct clk_fixed_factor *)res)->hw);
|
||||
}
|
||||
|
||||
static struct clk_hw *
|
||||
__clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
|
||||
const char *name, const char *parent_name, int index,
|
||||
unsigned long flags, unsigned int mult, unsigned int div)
|
||||
unsigned long flags, unsigned int mult, unsigned int div,
|
||||
bool devm)
|
||||
{
|
||||
struct clk_fixed_factor *fix;
|
||||
struct clk_init_data init = { };
|
||||
@ -75,7 +81,15 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
|
||||
struct clk_hw *hw;
|
||||
int ret;
|
||||
|
||||
fix = kmalloc(sizeof(*fix), GFP_KERNEL);
|
||||
/* You can't use devm without a dev */
|
||||
if (devm && !dev)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (devm)
|
||||
fix = devres_alloc(devm_clk_hw_register_fixed_factor_release,
|
||||
sizeof(*fix), GFP_KERNEL);
|
||||
else
|
||||
fix = kmalloc(sizeof(*fix), GFP_KERNEL);
|
||||
if (!fix)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -99,9 +113,13 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
|
||||
else
|
||||
ret = of_clk_hw_register(np, hw);
|
||||
if (ret) {
|
||||
kfree(fix);
|
||||
if (devm)
|
||||
devres_free(fix);
|
||||
else
|
||||
kfree(fix);
|
||||
hw = ERR_PTR(ret);
|
||||
}
|
||||
} else if (devm)
|
||||
devres_add(dev, fix);
|
||||
|
||||
return hw;
|
||||
}
|
||||
@ -111,7 +129,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
|
||||
unsigned int mult, unsigned int div)
|
||||
{
|
||||
return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
|
||||
flags, mult, div);
|
||||
flags, mult, div, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
|
||||
|
||||
@ -153,6 +171,15 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor);
|
||||
|
||||
struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
|
||||
const char *name, const char *parent_name, unsigned long flags,
|
||||
unsigned int mult, unsigned int div)
|
||||
{
|
||||
return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
|
||||
flags, mult, div, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id set_rate_parent_matches[] = {
|
||||
{ .compatible = "allwinner,sun4i-a10-pll3-2x-clk" },
|
||||
@ -185,7 +212,7 @@ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
|
||||
flags |= CLK_SET_RATE_PARENT;
|
||||
|
||||
hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0,
|
||||
flags, mult, div);
|
||||
flags, mult, div, false);
|
||||
if (IS_ERR(hw)) {
|
||||
/*
|
||||
* Clear OF_POPULATED flag so that clock registration can be
|
||||
|
@ -941,7 +941,9 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
|
||||
const char *name, const char *parent_name, unsigned long flags,
|
||||
unsigned int mult, unsigned int div);
|
||||
void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
|
||||
|
||||
struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
|
||||
const char *name, const char *parent_name, unsigned long flags,
|
||||
unsigned int mult, unsigned int div);
|
||||
/**
|
||||
* struct clk_fractional_divider - adjustable fractional divider clock
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user