Skip to content

Commit 0b9266d

Browse files
fifteenhexbebarino
authored andcommitted
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 4f83b52 commit 0b9266d

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

drivers/clk/clk-fixed-factor.c

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,32 @@ const struct clk_ops clk_fixed_factor_ops = {
6464
};
6565
EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
6666

67+
static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void *res)
68+
{
69+
clk_hw_unregister_fixed_factor(&((struct clk_fixed_factor *)res)->hw);
70+
}
71+
6772
static struct clk_hw *
6873
__clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
6974
const char *name, const char *parent_name, int index,
70-
unsigned long flags, unsigned int mult, unsigned int div)
75+
unsigned long flags, unsigned int mult, unsigned int div,
76+
bool devm)
7177
{
7278
struct clk_fixed_factor *fix;
7379
struct clk_init_data init = { };
7480
struct clk_parent_data pdata = { .index = index };
7581
struct clk_hw *hw;
7682
int ret;
7783

78-
fix = kmalloc(sizeof(*fix), GFP_KERNEL);
84+
/* You can't use devm without a dev */
85+
if (devm && !dev)
86+
return ERR_PTR(-EINVAL);
87+
88+
if (devm)
89+
fix = devres_alloc(devm_clk_hw_register_fixed_factor_release,
90+
sizeof(*fix), GFP_KERNEL);
91+
else
92+
fix = kmalloc(sizeof(*fix), GFP_KERNEL);
7993
if (!fix)
8094
return ERR_PTR(-ENOMEM);
8195

@@ -99,9 +113,13 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
99113
else
100114
ret = of_clk_hw_register(np, hw);
101115
if (ret) {
102-
kfree(fix);
116+
if (devm)
117+
devres_free(fix);
118+
else
119+
kfree(fix);
103120
hw = ERR_PTR(ret);
104-
}
121+
} else if (devm)
122+
devres_add(dev, fix);
105123

106124
return hw;
107125
}
@@ -111,7 +129,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
111129
unsigned int mult, unsigned int div)
112130
{
113131
return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
114-
flags, mult, div);
132+
flags, mult, div, false);
115133
}
116134
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
117135

@@ -153,6 +171,15 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw)
153171
}
154172
EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor);
155173

174+
struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
175+
const char *name, const char *parent_name, unsigned long flags,
176+
unsigned int mult, unsigned int div)
177+
{
178+
return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
179+
flags, mult, div, true);
180+
}
181+
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor);
182+
156183
#ifdef CONFIG_OF
157184
static const struct of_device_id set_rate_parent_matches[] = {
158185
{ .compatible = "allwinner,sun4i-a10-pll3-2x-clk" },
@@ -185,7 +212,7 @@ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
185212
flags |= CLK_SET_RATE_PARENT;
186213

187214
hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0,
188-
flags, mult, div);
215+
flags, mult, div, false);
189216
if (IS_ERR(hw)) {
190217
/*
191218
* Clear OF_POPULATED flag so that clock registration can be

include/linux/clk-provider.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,9 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
941941
const char *name, const char *parent_name, unsigned long flags,
942942
unsigned int mult, unsigned int div);
943943
void clk_hw_unregister_fixed_factor(struct clk_hw *hw);
944-
944+
struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
945+
const char *name, const char *parent_name, unsigned long flags,
946+
unsigned int mult, unsigned int div);
945947
/**
946948
* struct clk_fractional_divider - adjustable fractional divider clock
947949
*

0 commit comments

Comments
 (0)