xref: /openbmc/linux/drivers/regulator/devres.c (revision 4a075bd4)
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 static void devm_regulator_release(struct device *dev, void *res)
23 {
24 	regulator_put(*(struct regulator **)res);
25 }
26 
27 static struct regulator *_devm_regulator_get(struct device *dev, const char *id,
28 					     int get_type)
29 {
30 	struct regulator **ptr, *regulator;
31 
32 	ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
33 	if (!ptr)
34 		return ERR_PTR(-ENOMEM);
35 
36 	regulator = _regulator_get(dev, id, get_type);
37 	if (!IS_ERR(regulator)) {
38 		*ptr = regulator;
39 		devres_add(dev, ptr);
40 	} else {
41 		devres_free(ptr);
42 	}
43 
44 	return regulator;
45 }
46 
47 /**
48  * devm_regulator_get - Resource managed regulator_get()
49  * @dev: device for regulator "consumer"
50  * @id: Supply name or regulator ID.
51  *
52  * Managed regulator_get(). Regulators returned from this function are
53  * automatically regulator_put() on driver detach. See regulator_get() for more
54  * information.
55  */
56 struct regulator *devm_regulator_get(struct device *dev, const char *id)
57 {
58 	return _devm_regulator_get(dev, id, NORMAL_GET);
59 }
60 EXPORT_SYMBOL_GPL(devm_regulator_get);
61 
62 /**
63  * devm_regulator_get_exclusive - Resource managed regulator_get_exclusive()
64  * @dev: device for regulator "consumer"
65  * @id: Supply name or regulator ID.
66  *
67  * Managed regulator_get_exclusive(). Regulators returned from this function
68  * are automatically regulator_put() on driver detach. See regulator_get() for
69  * more information.
70  */
71 struct regulator *devm_regulator_get_exclusive(struct device *dev,
72 					       const char *id)
73 {
74 	return _devm_regulator_get(dev, id, EXCLUSIVE_GET);
75 }
76 EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive);
77 
78 /**
79  * devm_regulator_get_optional - Resource managed regulator_get_optional()
80  * @dev: device for regulator "consumer"
81  * @id: Supply name or regulator ID.
82  *
83  * Managed regulator_get_optional(). Regulators returned from this
84  * function are automatically regulator_put() on driver detach. See
85  * regulator_get_optional() for more information.
86  */
87 struct regulator *devm_regulator_get_optional(struct device *dev,
88 					      const char *id)
89 {
90 	return _devm_regulator_get(dev, id, OPTIONAL_GET);
91 }
92 EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
93 
94 static int devm_regulator_match(struct device *dev, void *res, void *data)
95 {
96 	struct regulator **r = res;
97 	if (!r || !*r) {
98 		WARN_ON(!r || !*r);
99 		return 0;
100 	}
101 	return *r == data;
102 }
103 
104 /**
105  * devm_regulator_put - Resource managed regulator_put()
106  * @regulator: regulator to free
107  *
108  * Deallocate a regulator allocated with devm_regulator_get(). Normally
109  * this function will not need to be called and the resource management
110  * code will ensure that the resource is freed.
111  */
112 void devm_regulator_put(struct regulator *regulator)
113 {
114 	int rc;
115 
116 	rc = devres_release(regulator->dev, devm_regulator_release,
117 			    devm_regulator_match, regulator);
118 	if (rc != 0)
119 		WARN_ON(rc);
120 }
121 EXPORT_SYMBOL_GPL(devm_regulator_put);
122 
123 struct regulator_bulk_devres {
124 	struct regulator_bulk_data *consumers;
125 	int num_consumers;
126 };
127 
128 static void devm_regulator_bulk_release(struct device *dev, void *res)
129 {
130 	struct regulator_bulk_devres *devres = res;
131 
132 	regulator_bulk_free(devres->num_consumers, devres->consumers);
133 }
134 
135 /**
136  * devm_regulator_bulk_get - managed get multiple regulator consumers
137  *
138  * @dev:           Device to supply
139  * @num_consumers: Number of consumers to register
140  * @consumers:     Configuration of consumers; clients are stored here.
141  *
142  * @return 0 on success, an errno on failure.
143  *
144  * This helper function allows drivers to get several regulator
145  * consumers in one operation with management, the regulators will
146  * automatically be freed when the device is unbound.  If any of the
147  * regulators cannot be acquired then any regulators that were
148  * allocated will be freed before returning to the caller.
149  */
150 int devm_regulator_bulk_get(struct device *dev, int num_consumers,
151 			    struct regulator_bulk_data *consumers)
152 {
153 	struct regulator_bulk_devres *devres;
154 	int ret;
155 
156 	devres = devres_alloc(devm_regulator_bulk_release,
157 			      sizeof(*devres), GFP_KERNEL);
158 	if (!devres)
159 		return -ENOMEM;
160 
161 	ret = regulator_bulk_get(dev, num_consumers, consumers);
162 	if (!ret) {
163 		devres->consumers = consumers;
164 		devres->num_consumers = num_consumers;
165 		devres_add(dev, devres);
166 	} else {
167 		devres_free(devres);
168 	}
169 
170 	return ret;
171 }
172 EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
173 
174 static void devm_rdev_release(struct device *dev, void *res)
175 {
176 	regulator_unregister(*(struct regulator_dev **)res);
177 }
178 
179 /**
180  * devm_regulator_register - Resource managed regulator_register()
181  * @regulator_desc: regulator to register
182  * @config: runtime configuration for regulator
183  *
184  * Called by regulator drivers to register a regulator.  Returns a
185  * valid pointer to struct regulator_dev on success or an ERR_PTR() on
186  * error.  The regulator will automatically be released when the device
187  * is unbound.
188  */
189 struct regulator_dev *devm_regulator_register(struct device *dev,
190 				  const struct regulator_desc *regulator_desc,
191 				  const struct regulator_config *config)
192 {
193 	struct regulator_dev **ptr, *rdev;
194 
195 	ptr = devres_alloc(devm_rdev_release, sizeof(*ptr),
196 			   GFP_KERNEL);
197 	if (!ptr)
198 		return ERR_PTR(-ENOMEM);
199 
200 	rdev = regulator_register(regulator_desc, config);
201 	if (!IS_ERR(rdev)) {
202 		*ptr = rdev;
203 		devres_add(dev, ptr);
204 	} else {
205 		devres_free(ptr);
206 	}
207 
208 	return rdev;
209 }
210 EXPORT_SYMBOL_GPL(devm_regulator_register);
211 
212 static int devm_rdev_match(struct device *dev, void *res, void *data)
213 {
214 	struct regulator_dev **r = res;
215 	if (!r || !*r) {
216 		WARN_ON(!r || !*r);
217 		return 0;
218 	}
219 	return *r == data;
220 }
221 
222 /**
223  * devm_regulator_unregister - Resource managed regulator_unregister()
224  * @regulator: regulator to free
225  *
226  * Unregister a regulator registered with devm_regulator_register().
227  * Normally this function will not need to be called and the resource
228  * management code will ensure that the resource is freed.
229  */
230 void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev)
231 {
232 	int rc;
233 
234 	rc = devres_release(dev, devm_rdev_release, devm_rdev_match, rdev);
235 	if (rc != 0)
236 		WARN_ON(rc);
237 }
238 EXPORT_SYMBOL_GPL(devm_regulator_unregister);
239 
240 struct regulator_supply_alias_match {
241 	struct device *dev;
242 	const char *id;
243 };
244 
245 static int devm_regulator_match_supply_alias(struct device *dev, void *res,
246 					     void *data)
247 {
248 	struct regulator_supply_alias_match *match = res;
249 	struct regulator_supply_alias_match *target = data;
250 
251 	return match->dev == target->dev && strcmp(match->id, target->id) == 0;
252 }
253 
254 static void devm_regulator_destroy_supply_alias(struct device *dev, void *res)
255 {
256 	struct regulator_supply_alias_match *match = res;
257 
258 	regulator_unregister_supply_alias(match->dev, match->id);
259 }
260 
261 /**
262  * devm_regulator_register_supply_alias - Resource managed
263  * regulator_register_supply_alias()
264  *
265  * @dev: device that will be given as the regulator "consumer"
266  * @id: Supply name or regulator ID
267  * @alias_dev: device that should be used to lookup the supply
268  * @alias_id: Supply name or regulator ID that should be used to lookup the
269  * supply
270  *
271  * The supply alias will automatically be unregistered when the source
272  * device is unbound.
273  */
274 int devm_regulator_register_supply_alias(struct device *dev, const char *id,
275 					 struct device *alias_dev,
276 					 const char *alias_id)
277 {
278 	struct regulator_supply_alias_match *match;
279 	int ret;
280 
281 	match = devres_alloc(devm_regulator_destroy_supply_alias,
282 			   sizeof(struct regulator_supply_alias_match),
283 			   GFP_KERNEL);
284 	if (!match)
285 		return -ENOMEM;
286 
287 	match->dev = dev;
288 	match->id = id;
289 
290 	ret = regulator_register_supply_alias(dev, id, alias_dev, alias_id);
291 	if (ret < 0) {
292 		devres_free(match);
293 		return ret;
294 	}
295 
296 	devres_add(dev, match);
297 
298 	return 0;
299 }
300 EXPORT_SYMBOL_GPL(devm_regulator_register_supply_alias);
301 
302 /**
303  * devm_regulator_unregister_supply_alias - Resource managed
304  * regulator_unregister_supply_alias()
305  *
306  * @dev: device that will be given as the regulator "consumer"
307  * @id: Supply name or regulator ID
308  *
309  * Unregister an alias registered with
310  * devm_regulator_register_supply_alias(). Normally this function
311  * will not need to be called and the resource management code
312  * will ensure that the resource is freed.
313  */
314 void devm_regulator_unregister_supply_alias(struct device *dev, const char *id)
315 {
316 	struct regulator_supply_alias_match match;
317 	int rc;
318 
319 	match.dev = dev;
320 	match.id = id;
321 
322 	rc = devres_release(dev, devm_regulator_destroy_supply_alias,
323 			    devm_regulator_match_supply_alias, &match);
324 	if (rc != 0)
325 		WARN_ON(rc);
326 }
327 EXPORT_SYMBOL_GPL(devm_regulator_unregister_supply_alias);
328 
329 /**
330  * devm_regulator_bulk_register_supply_alias - Managed register
331  * multiple aliases
332  *
333  * @dev: device that will be given as the regulator "consumer"
334  * @id: List of supply names or regulator IDs
335  * @alias_dev: device that should be used to lookup the supply
336  * @alias_id: List of supply names or regulator IDs that should be used to
337  * lookup the supply
338  * @num_id: Number of aliases to register
339  *
340  * @return 0 on success, an errno on failure.
341  *
342  * This helper function allows drivers to register several supply
343  * aliases in one operation, the aliases will be automatically
344  * unregisters when the source device is unbound.  If any of the
345  * aliases cannot be registered any aliases that were registered
346  * will be removed before returning to the caller.
347  */
348 int devm_regulator_bulk_register_supply_alias(struct device *dev,
349 					      const char *const *id,
350 					      struct device *alias_dev,
351 					      const char *const *alias_id,
352 					      int num_id)
353 {
354 	int i;
355 	int ret;
356 
357 	for (i = 0; i < num_id; ++i) {
358 		ret = devm_regulator_register_supply_alias(dev, id[i],
359 							   alias_dev,
360 							   alias_id[i]);
361 		if (ret < 0)
362 			goto err;
363 	}
364 
365 	return 0;
366 
367 err:
368 	dev_err(dev,
369 		"Failed to create supply alias %s,%s -> %s,%s\n",
370 		id[i], dev_name(dev), alias_id[i], dev_name(alias_dev));
371 
372 	while (--i >= 0)
373 		devm_regulator_unregister_supply_alias(dev, id[i]);
374 
375 	return ret;
376 }
377 EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias);
378 
379 /**
380  * devm_regulator_bulk_unregister_supply_alias - Managed unregister
381  * multiple aliases
382  *
383  * @dev: device that will be given as the regulator "consumer"
384  * @id: List of supply names or regulator IDs
385  * @num_id: Number of aliases to unregister
386  *
387  * Unregister aliases registered with
388  * devm_regulator_bulk_register_supply_alias(). Normally this function
389  * will not need to be called and the resource management code
390  * will ensure that the resource is freed.
391  */
392 void devm_regulator_bulk_unregister_supply_alias(struct device *dev,
393 						 const char *const *id,
394 						 int num_id)
395 {
396 	int i;
397 
398 	for (i = 0; i < num_id; ++i)
399 		devm_regulator_unregister_supply_alias(dev, id[i]);
400 }
401 EXPORT_SYMBOL_GPL(devm_regulator_bulk_unregister_supply_alias);
402 
403 struct regulator_notifier_match {
404 	struct regulator *regulator;
405 	struct notifier_block *nb;
406 };
407 
408 static int devm_regulator_match_notifier(struct device *dev, void *res,
409 					 void *data)
410 {
411 	struct regulator_notifier_match *match = res;
412 	struct regulator_notifier_match *target = data;
413 
414 	return match->regulator == target->regulator && match->nb == target->nb;
415 }
416 
417 static void devm_regulator_destroy_notifier(struct device *dev, void *res)
418 {
419 	struct regulator_notifier_match *match = res;
420 
421 	regulator_unregister_notifier(match->regulator, match->nb);
422 }
423 
424 /**
425  * devm_regulator_register_notifier - Resource managed
426  * regulator_register_notifier
427  *
428  * @regulator: regulator source
429  * @nb: notifier block
430  *
431  * The notifier will be registers under the consumer device and be
432  * automatically be unregistered when the source device is unbound.
433  */
434 int devm_regulator_register_notifier(struct regulator *regulator,
435 				     struct notifier_block *nb)
436 {
437 	struct regulator_notifier_match *match;
438 	int ret;
439 
440 	match = devres_alloc(devm_regulator_destroy_notifier,
441 			     sizeof(struct regulator_notifier_match),
442 			     GFP_KERNEL);
443 	if (!match)
444 		return -ENOMEM;
445 
446 	match->regulator = regulator;
447 	match->nb = nb;
448 
449 	ret = regulator_register_notifier(regulator, nb);
450 	if (ret < 0) {
451 		devres_free(match);
452 		return ret;
453 	}
454 
455 	devres_add(regulator->dev, match);
456 
457 	return 0;
458 }
459 EXPORT_SYMBOL_GPL(devm_regulator_register_notifier);
460 
461 /**
462  * devm_regulator_unregister_notifier - Resource managed
463  * regulator_unregister_notifier()
464  *
465  * @regulator: regulator source
466  * @nb: notifier block
467  *
468  * Unregister a notifier registered with devm_regulator_register_notifier().
469  * Normally this function will not need to be called and the resource
470  * management code will ensure that the resource is freed.
471  */
472 void devm_regulator_unregister_notifier(struct regulator *regulator,
473 					struct notifier_block *nb)
474 {
475 	struct regulator_notifier_match match;
476 	int rc;
477 
478 	match.regulator = regulator;
479 	match.nb = nb;
480 
481 	rc = devres_release(regulator->dev, devm_regulator_destroy_notifier,
482 			    devm_regulator_match_notifier, &match);
483 	if (rc != 0)
484 		WARN_ON(rc);
485 }
486 EXPORT_SYMBOL_GPL(devm_regulator_unregister_notifier);
487