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