xref: /openbmc/linux/drivers/regulator/devres.c (revision 78700c0a)
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 							    consumers[i].optional ?
170 								OPTIONAL_GET :
171 								NORMAL_GET);
172 		if (IS_ERR(consumers[i].consumer)) {
173 			ret = PTR_ERR(consumers[i].consumer);
174 			dev_err(dev, "Failed to get supply '%s': %d\n",
175 				consumers[i].supply, ret);
176 			consumers[i].consumer = NULL;
177 			goto err;
178 		}
179 	}
180 
181 	return 0;
182 
183 err:
184 	for (i = 0; i < num_consumers && consumers[i].consumer; i++)
185 		devm_regulator_put(consumers[i].consumer);
186 
187 	return ret;
188 }
189 EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
190 
191 static void devm_rdev_release(struct device *dev, void *res)
192 {
193 	regulator_unregister(*(struct regulator_dev **)res);
194 }
195 
196 /**
197  * devm_regulator_register - Resource managed regulator_register()
198  * @regulator_desc: regulator to register
199  * @config: runtime configuration for regulator
200  *
201  * Called by regulator drivers to register a regulator.  Returns a
202  * valid pointer to struct regulator_dev on success or an ERR_PTR() on
203  * error.  The regulator will automatically be released when the device
204  * is unbound.
205  */
206 struct regulator_dev *devm_regulator_register(struct device *dev,
207 				  const struct regulator_desc *regulator_desc,
208 				  const struct regulator_config *config)
209 {
210 	struct regulator_dev **ptr, *rdev;
211 
212 	ptr = devres_alloc(devm_rdev_release, sizeof(*ptr),
213 			   GFP_KERNEL);
214 	if (!ptr)
215 		return ERR_PTR(-ENOMEM);
216 
217 	rdev = regulator_register(regulator_desc, config);
218 	if (!IS_ERR(rdev)) {
219 		*ptr = rdev;
220 		devres_add(dev, ptr);
221 	} else {
222 		devres_free(ptr);
223 	}
224 
225 	return rdev;
226 }
227 EXPORT_SYMBOL_GPL(devm_regulator_register);
228 
229 static int devm_rdev_match(struct device *dev, void *res, void *data)
230 {
231 	struct regulator_dev **r = res;
232 	if (!r || !*r) {
233 		WARN_ON(!r || !*r);
234 		return 0;
235 	}
236 	return *r == data;
237 }
238 
239 /**
240  * devm_regulator_unregister - Resource managed regulator_unregister()
241  * @regulator: regulator to free
242  *
243  * Unregister a regulator registered with devm_regulator_register().
244  * Normally this function will not need to be called and the resource
245  * management code will ensure that the resource is freed.
246  */
247 void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev)
248 {
249 	int rc;
250 
251 	rc = devres_release(dev, devm_rdev_release, devm_rdev_match, rdev);
252 	if (rc != 0)
253 		WARN_ON(rc);
254 }
255 EXPORT_SYMBOL_GPL(devm_regulator_unregister);
256 
257 struct regulator_supply_alias_match {
258 	struct device *dev;
259 	const char *id;
260 };
261 
262 static int devm_regulator_match_supply_alias(struct device *dev, void *res,
263 					     void *data)
264 {
265 	struct regulator_supply_alias_match *match = res;
266 	struct regulator_supply_alias_match *target = data;
267 
268 	return match->dev == target->dev && strcmp(match->id, target->id) == 0;
269 }
270 
271 static void devm_regulator_destroy_supply_alias(struct device *dev, void *res)
272 {
273 	struct regulator_supply_alias_match *match = res;
274 
275 	regulator_unregister_supply_alias(match->dev, match->id);
276 }
277 
278 /**
279  * devm_regulator_register_supply_alias - Resource managed
280  * regulator_register_supply_alias()
281  *
282  * @dev: device that will be given as the regulator "consumer"
283  * @id: Supply name or regulator ID
284  * @alias_dev: device that should be used to lookup the supply
285  * @alias_id: Supply name or regulator ID that should be used to lookup the
286  * supply
287  *
288  * The supply alias will automatically be unregistered when the source
289  * device is unbound.
290  */
291 int devm_regulator_register_supply_alias(struct device *dev, const char *id,
292 					 struct device *alias_dev,
293 					 const char *alias_id)
294 {
295 	struct regulator_supply_alias_match *match;
296 	int ret;
297 
298 	match = devres_alloc(devm_regulator_destroy_supply_alias,
299 			   sizeof(struct regulator_supply_alias_match),
300 			   GFP_KERNEL);
301 	if (!match)
302 		return -ENOMEM;
303 
304 	match->dev = dev;
305 	match->id = id;
306 
307 	ret = regulator_register_supply_alias(dev, id, alias_dev, alias_id);
308 	if (ret < 0) {
309 		devres_free(match);
310 		return ret;
311 	}
312 
313 	devres_add(dev, match);
314 
315 	return 0;
316 }
317 EXPORT_SYMBOL_GPL(devm_regulator_register_supply_alias);
318 
319 /**
320  * devm_regulator_unregister_supply_alias - Resource managed
321  * regulator_unregister_supply_alias()
322  *
323  * @dev: device that will be given as the regulator "consumer"
324  * @id: Supply name or regulator ID
325  *
326  * Unregister an alias registered with
327  * devm_regulator_register_supply_alias(). Normally this function
328  * will not need to be called and the resource management code
329  * will ensure that the resource is freed.
330  */
331 void devm_regulator_unregister_supply_alias(struct device *dev, const char *id)
332 {
333 	struct regulator_supply_alias_match match;
334 	int rc;
335 
336 	match.dev = dev;
337 	match.id = id;
338 
339 	rc = devres_release(dev, devm_regulator_destroy_supply_alias,
340 			    devm_regulator_match_supply_alias, &match);
341 	if (rc != 0)
342 		WARN_ON(rc);
343 }
344 EXPORT_SYMBOL_GPL(devm_regulator_unregister_supply_alias);
345 
346 /**
347  * devm_regulator_bulk_register_supply_alias - Managed register
348  * multiple aliases
349  *
350  * @dev: device that will be given as the regulator "consumer"
351  * @id: List of supply names or regulator IDs
352  * @alias_dev: device that should be used to lookup the supply
353  * @alias_id: List of supply names or regulator IDs that should be used to
354  * lookup the supply
355  * @num_id: Number of aliases to register
356  *
357  * @return 0 on success, an errno on failure.
358  *
359  * This helper function allows drivers to register several supply
360  * aliases in one operation, the aliases will be automatically
361  * unregisters when the source device is unbound.  If any of the
362  * aliases cannot be registered any aliases that were registered
363  * will be removed before returning to the caller.
364  */
365 int devm_regulator_bulk_register_supply_alias(struct device *dev,
366 					      const char *const *id,
367 					      struct device *alias_dev,
368 					      const char *const *alias_id,
369 					      int num_id)
370 {
371 	int i;
372 	int ret;
373 
374 	for (i = 0; i < num_id; ++i) {
375 		ret = devm_regulator_register_supply_alias(dev, id[i],
376 							   alias_dev,
377 							   alias_id[i]);
378 		if (ret < 0)
379 			goto err;
380 	}
381 
382 	return 0;
383 
384 err:
385 	dev_err(dev,
386 		"Failed to create supply alias %s,%s -> %s,%s\n",
387 		id[i], dev_name(dev), alias_id[i], dev_name(alias_dev));
388 
389 	while (--i >= 0)
390 		devm_regulator_unregister_supply_alias(dev, id[i]);
391 
392 	return ret;
393 }
394 EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias);
395 
396 /**
397  * devm_regulator_bulk_unregister_supply_alias - Managed unregister
398  * multiple aliases
399  *
400  * @dev: device that will be given as the regulator "consumer"
401  * @id: List of supply names or regulator IDs
402  * @num_id: Number of aliases to unregister
403  *
404  * Unregister aliases registered with
405  * devm_regulator_bulk_register_supply_alias(). Normally this function
406  * will not need to be called and the resource management code
407  * will ensure that the resource is freed.
408  */
409 void devm_regulator_bulk_unregister_supply_alias(struct device *dev,
410 						 const char *const *id,
411 						 int num_id)
412 {
413 	int i;
414 
415 	for (i = 0; i < num_id; ++i)
416 		devm_regulator_unregister_supply_alias(dev, id[i]);
417 }
418 EXPORT_SYMBOL_GPL(devm_regulator_bulk_unregister_supply_alias);
419 
420 struct regulator_notifier_match {
421 	struct regulator *regulator;
422 	struct notifier_block *nb;
423 };
424 
425 static int devm_regulator_match_notifier(struct device *dev, void *res,
426 					 void *data)
427 {
428 	struct regulator_notifier_match *match = res;
429 	struct regulator_notifier_match *target = data;
430 
431 	return match->regulator == target->regulator && match->nb == target->nb;
432 }
433 
434 static void devm_regulator_destroy_notifier(struct device *dev, void *res)
435 {
436 	struct regulator_notifier_match *match = res;
437 
438 	regulator_unregister_notifier(match->regulator, match->nb);
439 }
440 
441 /**
442  * devm_regulator_register_notifier - Resource managed
443  * regulator_register_notifier
444  *
445  * @regulator: regulator source
446  * @nb: notifier block
447  *
448  * The notifier will be registers under the consumer device and be
449  * automatically be unregistered when the source device is unbound.
450  */
451 int devm_regulator_register_notifier(struct regulator *regulator,
452 				     struct notifier_block *nb)
453 {
454 	struct regulator_notifier_match *match;
455 	int ret;
456 
457 	match = devres_alloc(devm_regulator_destroy_notifier,
458 			     sizeof(struct regulator_notifier_match),
459 			     GFP_KERNEL);
460 	if (!match)
461 		return -ENOMEM;
462 
463 	match->regulator = regulator;
464 	match->nb = nb;
465 
466 	ret = regulator_register_notifier(regulator, nb);
467 	if (ret < 0) {
468 		devres_free(match);
469 		return ret;
470 	}
471 
472 	devres_add(regulator->dev, match);
473 
474 	return 0;
475 }
476 EXPORT_SYMBOL_GPL(devm_regulator_register_notifier);
477 
478 /**
479  * devm_regulator_unregister_notifier - Resource managed
480  * regulator_unregister_notifier()
481  *
482  * @regulator: regulator source
483  * @nb: notifier block
484  *
485  * Unregister a notifier registered with devm_regulator_register_notifier().
486  * Normally this function will not need to be called and the resource
487  * management code will ensure that the resource is freed.
488  */
489 void devm_regulator_unregister_notifier(struct regulator *regulator,
490 					struct notifier_block *nb)
491 {
492 	struct regulator_notifier_match match;
493 	int rc;
494 
495 	match.regulator = regulator;
496 	match.nb = nb;
497 
498 	rc = devres_release(regulator->dev, devm_regulator_destroy_notifier,
499 			    devm_regulator_match_notifier, &match);
500 	if (rc != 0)
501 		WARN_ON(rc);
502 }
503 EXPORT_SYMBOL_GPL(devm_regulator_unregister_notifier);
504