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