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 = *(struct devm_clk_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_optional(struct device *dev, const char *id)
71 return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL);
73 EXPORT_SYMBOL(devm_clk_get_optional);
75 struct clk_bulk_devres {
76 struct clk_bulk_data *clks;
80 static void devm_clk_bulk_release(struct device *dev, void *res)
82 struct clk_bulk_devres *devres = res;
84 clk_bulk_put(devres->num_clks, devres->clks);
87 static int __devm_clk_bulk_get(struct device *dev, int num_clks,
88 struct clk_bulk_data *clks, bool optional)
90 struct clk_bulk_devres *devres;
93 devres = devres_alloc(devm_clk_bulk_release,
94 sizeof(*devres), GFP_KERNEL);
99 ret = clk_bulk_get_optional(dev, num_clks, clks);
101 ret = clk_bulk_get(dev, num_clks, clks);
104 devres->num_clks = num_clks;
105 devres_add(dev, devres);
113 int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
114 struct clk_bulk_data *clks)
116 return __devm_clk_bulk_get(dev, num_clks, clks, false);
118 EXPORT_SYMBOL_GPL(devm_clk_bulk_get);
120 int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks,
121 struct clk_bulk_data *clks)
123 return __devm_clk_bulk_get(dev, num_clks, clks, true);
125 EXPORT_SYMBOL_GPL(devm_clk_bulk_get_optional);
127 static void devm_clk_bulk_release_all(struct device *dev, void *res)
129 struct clk_bulk_devres *devres = res;
131 clk_bulk_put_all(devres->num_clks, devres->clks);
134 int __must_check devm_clk_bulk_get_all(struct device *dev,
135 struct clk_bulk_data **clks)
137 struct clk_bulk_devres *devres;
140 devres = devres_alloc(devm_clk_bulk_release_all,
141 sizeof(*devres), GFP_KERNEL);
145 ret = clk_bulk_get_all(dev, &devres->clks);
147 *clks = devres->clks;
148 devres->num_clks = ret;
149 devres_add(dev, devres);
156 EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all);
158 static int devm_clk_match(struct device *dev, void *res, void *data)
160 struct clk **c = res;
168 void devm_clk_put(struct device *dev, struct clk *clk)
172 ret = devres_release(dev, devm_clk_release, devm_clk_match, clk);
176 EXPORT_SYMBOL(devm_clk_put);
178 struct clk *devm_get_clk_from_child(struct device *dev,
179 struct device_node *np, const char *con_id)
181 struct clk **ptr, *clk;
183 ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
185 return ERR_PTR(-ENOMEM);
187 clk = of_clk_get_by_name(np, con_id);
190 devres_add(dev, ptr);
197 EXPORT_SYMBOL(devm_get_clk_from_child);