1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/device.h>
4 #include <linux/export.h>
7 struct devm_clk_state
{
9 void (*exit
)(struct clk
*clk
);
12 static void devm_clk_release(struct device
*dev
, void *res
)
14 struct devm_clk_state
*state
= res
;
17 state
->exit(state
->clk
);
22 static struct clk
*__devm_clk_get(struct device
*dev
, const char *id
,
23 struct clk
*(*get
)(struct device
*dev
, const char *id
),
24 int (*init
)(struct clk
*clk
),
25 void (*exit
)(struct clk
*clk
))
27 struct devm_clk_state
*state
;
31 state
= devres_alloc(devm_clk_release
, sizeof(*state
), GFP_KERNEL
);
33 return ERR_PTR(-ENOMEM
);
50 devres_add(dev
, state
);
63 struct clk
*devm_clk_get(struct device
*dev
, const char *id
)
65 return __devm_clk_get(dev
, id
, clk_get
, NULL
, NULL
);
67 EXPORT_SYMBOL(devm_clk_get
);
69 struct clk
*devm_clk_get_prepared(struct device
*dev
, const char *id
)
71 return __devm_clk_get(dev
, id
, clk_get
, clk_prepare
, clk_unprepare
);
73 EXPORT_SYMBOL_GPL(devm_clk_get_prepared
);
75 struct clk
*devm_clk_get_enabled(struct device
*dev
, const char *id
)
77 return __devm_clk_get(dev
, id
, clk_get
,
78 clk_prepare_enable
, clk_disable_unprepare
);
80 EXPORT_SYMBOL_GPL(devm_clk_get_enabled
);
82 struct clk
*devm_clk_get_optional(struct device
*dev
, const char *id
)
84 return __devm_clk_get(dev
, id
, clk_get_optional
, NULL
, NULL
);
86 EXPORT_SYMBOL(devm_clk_get_optional
);
88 struct clk
*devm_clk_get_optional_prepared(struct device
*dev
, const char *id
)
90 return __devm_clk_get(dev
, id
, clk_get_optional
,
91 clk_prepare
, clk_unprepare
);
93 EXPORT_SYMBOL_GPL(devm_clk_get_optional_prepared
);
95 struct clk
*devm_clk_get_optional_enabled(struct device
*dev
, const char *id
)
97 return __devm_clk_get(dev
, id
, clk_get_optional
,
98 clk_prepare_enable
, clk_disable_unprepare
);
100 EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled
);
102 struct clk
*devm_clk_get_optional_enabled_with_rate(struct device
*dev
,
109 clk
= __devm_clk_get(dev
, id
, clk_get_optional
, NULL
,
110 clk_disable_unprepare
);
112 return ERR_CAST(clk
);
114 ret
= clk_set_rate(clk
, rate
);
118 ret
= clk_prepare_enable(clk
);
125 devm_clk_put(dev
, clk
);
128 EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled_with_rate
);
130 struct clk_bulk_devres
{
131 struct clk_bulk_data
*clks
;
135 static void devm_clk_bulk_release(struct device
*dev
, void *res
)
137 struct clk_bulk_devres
*devres
= res
;
139 clk_bulk_put(devres
->num_clks
, devres
->clks
);
142 static int __devm_clk_bulk_get(struct device
*dev
, int num_clks
,
143 struct clk_bulk_data
*clks
, bool optional
)
145 struct clk_bulk_devres
*devres
;
148 devres
= devres_alloc(devm_clk_bulk_release
,
149 sizeof(*devres
), GFP_KERNEL
);
154 ret
= clk_bulk_get_optional(dev
, num_clks
, clks
);
156 ret
= clk_bulk_get(dev
, num_clks
, clks
);
159 devres
->num_clks
= num_clks
;
160 devres_add(dev
, devres
);
168 int __must_check
devm_clk_bulk_get(struct device
*dev
, int num_clks
,
169 struct clk_bulk_data
*clks
)
171 return __devm_clk_bulk_get(dev
, num_clks
, clks
, false);
173 EXPORT_SYMBOL_GPL(devm_clk_bulk_get
);
175 int __must_check
devm_clk_bulk_get_optional(struct device
*dev
, int num_clks
,
176 struct clk_bulk_data
*clks
)
178 return __devm_clk_bulk_get(dev
, num_clks
, clks
, true);
180 EXPORT_SYMBOL_GPL(devm_clk_bulk_get_optional
);
182 static void devm_clk_bulk_release_all(struct device
*dev
, void *res
)
184 struct clk_bulk_devres
*devres
= res
;
186 clk_bulk_put_all(devres
->num_clks
, devres
->clks
);
189 int __must_check
devm_clk_bulk_get_all(struct device
*dev
,
190 struct clk_bulk_data
**clks
)
192 struct clk_bulk_devres
*devres
;
195 devres
= devres_alloc(devm_clk_bulk_release_all
,
196 sizeof(*devres
), GFP_KERNEL
);
200 ret
= clk_bulk_get_all(dev
, &devres
->clks
);
202 *clks
= devres
->clks
;
203 devres
->num_clks
= ret
;
204 devres_add(dev
, devres
);
211 EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all
);
213 static void devm_clk_bulk_release_all_enable(struct device
*dev
, void *res
)
215 struct clk_bulk_devres
*devres
= res
;
217 clk_bulk_disable_unprepare(devres
->num_clks
, devres
->clks
);
218 clk_bulk_put_all(devres
->num_clks
, devres
->clks
);
221 int __must_check
devm_clk_bulk_get_all_enable(struct device
*dev
,
222 struct clk_bulk_data
**clks
)
224 struct clk_bulk_devres
*devres
;
227 devres
= devres_alloc(devm_clk_bulk_release_all_enable
,
228 sizeof(*devres
), GFP_KERNEL
);
232 ret
= clk_bulk_get_all(dev
, &devres
->clks
);
234 *clks
= devres
->clks
;
235 devres
->num_clks
= ret
;
241 ret
= clk_bulk_prepare_enable(devres
->num_clks
, *clks
);
243 devres_add(dev
, devres
);
245 clk_bulk_put_all(devres
->num_clks
, devres
->clks
);
251 EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enable
);
253 static int devm_clk_match(struct device
*dev
, void *res
, void *data
)
255 struct clk
**c
= res
;
263 void devm_clk_put(struct device
*dev
, struct clk
*clk
)
267 ret
= devres_release(dev
, devm_clk_release
, devm_clk_match
, clk
);
271 EXPORT_SYMBOL(devm_clk_put
);
273 struct clk
*devm_get_clk_from_child(struct device
*dev
,
274 struct device_node
*np
, const char *con_id
)
276 struct devm_clk_state
*state
;
279 state
= devres_alloc(devm_clk_release
, sizeof(*state
), GFP_KERNEL
);
281 return ERR_PTR(-ENOMEM
);
283 clk
= of_clk_get_by_name(np
, con_id
);
286 devres_add(dev
, state
);
293 EXPORT_SYMBOL(devm_get_clk_from_child
);