xref: /openbmc/linux/drivers/regulator/devres.c (revision 79f08d9e)
1 /*
2  * devres.c  --  Voltage/Current Regulator framework devres implementation.
3  *
4  * Copyright 2013 Linaro Ltd
5  *
6  *  This program is free software; you can redistribute  it and/or modify it
7  *  under  the terms of  the GNU General  Public License as published by the
8  *  Free Software Foundation;  either version 2 of the  License, or (at your
9  *  option) any later version.
10  *
11  */
12 
13 #include <linux/kernel.h>
14 #include <linux/err.h>
15 #include <linux/regmap.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/regulator/driver.h>
18 #include <linux/module.h>
19 
20 #include "internal.h"
21 
22 enum {
23 	NORMAL_GET,
24 	EXCLUSIVE_GET,
25 	OPTIONAL_GET,
26 };
27 
28 static void devm_regulator_release(struct device *dev, void *res)
29 {
30 	regulator_put(*(struct regulator **)res);
31 }
32 
33 static struct regulator *_devm_regulator_get(struct device *dev, const char *id,
34 					     int get_type)
35 {
36 	struct regulator **ptr, *regulator;
37 
38 	ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
39 	if (!ptr)
40 		return ERR_PTR(-ENOMEM);
41 
42 	switch (get_type) {
43 	case NORMAL_GET:
44 		regulator = regulator_get(dev, id);
45 		break;
46 	case EXCLUSIVE_GET:
47 		regulator = regulator_get_exclusive(dev, id);
48 		break;
49 	case OPTIONAL_GET:
50 		regulator = regulator_get_optional(dev, id);
51 		break;
52 	default:
53 		regulator = ERR_PTR(-EINVAL);
54 	}
55 
56 	if (!IS_ERR(regulator)) {
57 		*ptr = regulator;
58 		devres_add(dev, ptr);
59 	} else {
60 		devres_free(ptr);
61 	}
62 
63 	return regulator;
64 }
65 
66 /**
67  * devm_regulator_get - Resource managed regulator_get()
68  * @dev: device for regulator "consumer"
69  * @id: Supply name or regulator ID.
70  *
71  * Managed regulator_get(). Regulators returned from this function are
72  * automatically regulator_put() on driver detach. See regulator_get() for more
73  * information.
74  */
75 struct regulator *devm_regulator_get(struct device *dev, const char *id)
76 {
77 	return _devm_regulator_get(dev, id, NORMAL_GET);
78 }
79 EXPORT_SYMBOL_GPL(devm_regulator_get);
80 
81 /**
82  * devm_regulator_get_exclusive - Resource managed regulator_get_exclusive()
83  * @dev: device for regulator "consumer"
84  * @id: Supply name or regulator ID.
85  *
86  * Managed regulator_get_exclusive(). Regulators returned from this function
87  * are automatically regulator_put() on driver detach. See regulator_get() for
88  * more information.
89  */
90 struct regulator *devm_regulator_get_exclusive(struct device *dev,
91 					       const char *id)
92 {
93 	return _devm_regulator_get(dev, id, EXCLUSIVE_GET);
94 }
95 EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive);
96 
97 /**
98  * devm_regulator_get_optional - Resource managed regulator_get_optional()
99  * @dev: device for regulator "consumer"
100  * @id: Supply name or regulator ID.
101  *
102  * Managed regulator_get_optional(). Regulators returned from this
103  * function are automatically regulator_put() on driver detach. See
104  * regulator_get_optional() for more information.
105  */
106 struct regulator *devm_regulator_get_optional(struct device *dev,
107 					      const char *id)
108 {
109 	return _devm_regulator_get(dev, id, OPTIONAL_GET);
110 }
111 EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
112 
113 static int devm_regulator_match(struct device *dev, void *res, void *data)
114 {
115 	struct regulator **r = res;
116 	if (!r || !*r) {
117 		WARN_ON(!r || !*r);
118 		return 0;
119 	}
120 	return *r == data;
121 }
122 
123 /**
124  * devm_regulator_put - Resource managed regulator_put()
125  * @regulator: regulator to free
126  *
127  * Deallocate a regulator allocated with devm_regulator_get(). Normally
128  * this function will not need to be called and the resource management
129  * code will ensure that the resource is freed.
130  */
131 void devm_regulator_put(struct regulator *regulator)
132 {
133 	int rc;
134 
135 	rc = devres_release(regulator->dev, devm_regulator_release,
136 			    devm_regulator_match, regulator);
137 	if (rc != 0)
138 		WARN_ON(rc);
139 }
140 EXPORT_SYMBOL_GPL(devm_regulator_put);
141 
142 /**
143  * devm_regulator_bulk_get - managed get multiple regulator consumers
144  *
145  * @dev:           Device to supply
146  * @num_consumers: Number of consumers to register
147  * @consumers:     Configuration of consumers; clients are stored here.
148  *
149  * @return 0 on success, an errno on failure.
150  *
151  * This helper function allows drivers to get several regulator
152  * consumers in one operation with management, the regulators will
153  * automatically be freed when the device is unbound.  If any of the
154  * regulators cannot be acquired then any regulators that were
155  * allocated will be freed before returning to the caller.
156  */
157 int devm_regulator_bulk_get(struct device *dev, int num_consumers,
158 			    struct regulator_bulk_data *consumers)
159 {
160 	int i;
161 	int ret;
162 
163 	for (i = 0; i < num_consumers; i++)
164 		consumers[i].consumer = NULL;
165 
166 	for (i = 0; i < num_consumers; i++) {
167 		consumers[i].consumer = devm_regulator_get(dev,
168 							   consumers[i].supply);
169 		if (IS_ERR(consumers[i].consumer)) {
170 			ret = PTR_ERR(consumers[i].consumer);
171 			dev_err(dev, "Failed to get supply '%s': %d\n",
172 				consumers[i].supply, ret);
173 			consumers[i].consumer = NULL;
174 			goto err;
175 		}
176 	}
177 
178 	return 0;
179 
180 err:
181 	for (i = 0; i < num_consumers && consumers[i].consumer; i++)
182 		devm_regulator_put(consumers[i].consumer);
183 
184 	return ret;
185 }
186 EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
187 
188 static void devm_rdev_release(struct device *dev, void *res)
189 {
190 	regulator_unregister(*(struct regulator_dev **)res);
191 }
192 
193 /**
194  * devm_regulator_register - Resource managed regulator_register()
195  * @regulator_desc: regulator to register
196  * @config: runtime configuration for regulator
197  *
198  * Called by regulator drivers to register a regulator.  Returns a
199  * valid pointer to struct regulator_dev on success or an ERR_PTR() on
200  * error.  The regulator will automatically be released when the device
201  * is unbound.
202  */
203 struct regulator_dev *devm_regulator_register(struct device *dev,
204 				  const struct regulator_desc *regulator_desc,
205 				  const struct regulator_config *config)
206 {
207 	struct regulator_dev **ptr, *rdev;
208 
209 	ptr = devres_alloc(devm_rdev_release, sizeof(*ptr),
210 			   GFP_KERNEL);
211 	if (!ptr)
212 		return ERR_PTR(-ENOMEM);
213 
214 	rdev = regulator_register(regulator_desc, config);
215 	if (!IS_ERR(rdev)) {
216 		*ptr = rdev;
217 		devres_add(dev, ptr);
218 	} else {
219 		devres_free(ptr);
220 	}
221 
222 	return rdev;
223 }
224 EXPORT_SYMBOL_GPL(devm_regulator_register);
225 
226 static int devm_rdev_match(struct device *dev, void *res, void *data)
227 {
228 	struct regulator_dev **r = res;
229 	if (!r || !*r) {
230 		WARN_ON(!r || !*r);
231 		return 0;
232 	}
233 	return *r == data;
234 }
235 
236 /**
237  * devm_regulator_unregister - Resource managed regulator_unregister()
238  * @regulator: regulator to free
239  *
240  * Unregister a regulator registered with devm_regulator_register().
241  * Normally this function will not need to be called and the resource
242  * management code will ensure that the resource is freed.
243  */
244 void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev)
245 {
246 	int rc;
247 
248 	rc = devres_release(dev, devm_rdev_release, devm_rdev_match, rdev);
249 	if (rc != 0)
250 		WARN_ON(rc);
251 }
252 EXPORT_SYMBOL_GPL(devm_regulator_unregister);
253 
254 struct regulator_supply_alias_match {
255 	struct device *dev;
256 	const char *id;
257 };
258 
259 static int devm_regulator_match_supply_alias(struct device *dev, void *res,
260 					     void *data)
261 {
262 	struct regulator_supply_alias_match *match = res;
263 	struct regulator_supply_alias_match *target = data;
264 
265 	return match->dev == target->dev && strcmp(match->id, target->id) == 0;
266 }
267 
268 static void devm_regulator_destroy_supply_alias(struct device *dev, void *res)
269 {
270 	struct regulator_supply_alias_match *match = res;
271 
272 	regulator_unregister_supply_alias(match->dev, match->id);
273 }
274 
275 /**
276  * devm_regulator_register_supply_alias - Resource managed
277  * regulator_register_supply_alias()
278  *
279  * @dev: device that will be given as the regulator "consumer"
280  * @id: Supply name or regulator ID
281  * @alias_dev: device that should be used to lookup the supply
282  * @alias_id: Supply name or regulator ID that should be used to lookup the
283  * supply
284  *
285  * The supply alias will automatically be unregistered when the source
286  * device is unbound.
287  */
288 int devm_regulator_register_supply_alias(struct device *dev, const char *id,
289 					 struct device *alias_dev,
290 					 const char *alias_id)
291 {
292 	struct regulator_supply_alias_match *match;
293 	int ret;
294 
295 	match = devres_alloc(devm_regulator_destroy_supply_alias,
296 			   sizeof(struct regulator_supply_alias_match),
297 			   GFP_KERNEL);
298 	if (!match)
299 		return -ENOMEM;
300 
301 	match->dev = dev;
302 	match->id = id;
303 
304 	ret = regulator_register_supply_alias(dev, id, alias_dev, alias_id);
305 	if (ret < 0) {
306 		devres_free(match);
307 		return ret;
308 	}
309 
310 	devres_add(dev, match);
311 
312 	return 0;
313 }
314 EXPORT_SYMBOL_GPL(devm_regulator_register_supply_alias);
315 
316 /**
317  * devm_regulator_unregister_supply_alias - Resource managed
318  * regulator_unregister_supply_alias()
319  *
320  * @dev: device that will be given as the regulator "consumer"
321  * @id: Supply name or regulator ID
322  *
323  * Unregister an alias registered with
324  * devm_regulator_register_supply_alias(). Normally this function
325  * will not need to be called and the resource management code
326  * will ensure that the resource is freed.
327  */
328 void devm_regulator_unregister_supply_alias(struct device *dev, const char *id)
329 {
330 	struct regulator_supply_alias_match match;
331 	int rc;
332 
333 	match.dev = dev;
334 	match.id = id;
335 
336 	rc = devres_release(dev, devm_regulator_destroy_supply_alias,
337 			    devm_regulator_match_supply_alias, &match);
338 	if (rc != 0)
339 		WARN_ON(rc);
340 }
341 EXPORT_SYMBOL_GPL(devm_regulator_unregister_supply_alias);
342 
343 /**
344  * devm_regulator_bulk_register_supply_alias - Managed register
345  * multiple aliases
346  *
347  * @dev: device that will be given as the regulator "consumer"
348  * @id: List of supply names or regulator IDs
349  * @alias_dev: device that should be used to lookup the supply
350  * @alias_id: List of supply names or regulator IDs that should be used to
351  * lookup the supply
352  * @num_id: Number of aliases to register
353  *
354  * @return 0 on success, an errno on failure.
355  *
356  * This helper function allows drivers to register several supply
357  * aliases in one operation, the aliases will be automatically
358  * unregisters when the source device is unbound.  If any of the
359  * aliases cannot be registered any aliases that were registered
360  * will be removed before returning to the caller.
361  */
362 int devm_regulator_bulk_register_supply_alias(struct device *dev,
363 					      const char **id,
364 					      struct device *alias_dev,
365 					      const char **alias_id,
366 					      int num_id)
367 {
368 	int i;
369 	int ret;
370 
371 	for (i = 0; i < num_id; ++i) {
372 		ret = devm_regulator_register_supply_alias(dev, id[i],
373 							   alias_dev,
374 							   alias_id[i]);
375 		if (ret < 0)
376 			goto err;
377 	}
378 
379 	return 0;
380 
381 err:
382 	dev_err(dev,
383 		"Failed to create supply alias %s,%s -> %s,%s\n",
384 		id[i], dev_name(dev), alias_id[i], dev_name(alias_dev));
385 
386 	while (--i >= 0)
387 		devm_regulator_unregister_supply_alias(dev, id[i]);
388 
389 	return ret;
390 }
391 EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias);
392 
393 /**
394  * devm_regulator_bulk_unregister_supply_alias - Managed unregister
395  * multiple aliases
396  *
397  * @dev: device that will be given as the regulator "consumer"
398  * @id: List of supply names or regulator IDs
399  * @num_id: Number of aliases to unregister
400  *
401  * Unregister aliases registered with
402  * devm_regulator_bulk_register_supply_alias(). Normally this function
403  * will not need to be called and the resource management code
404  * will ensure that the resource is freed.
405  */
406 void devm_regulator_bulk_unregister_supply_alias(struct device *dev,
407 						 const char **id,
408 						 int num_id)
409 {
410 	int i;
411 
412 	for (i = 0; i < num_id; ++i)
413 		devm_regulator_unregister_supply_alias(dev, id[i]);
414 }
415 EXPORT_SYMBOL_GPL(devm_regulator_bulk_unregister_supply_alias);
416