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 
devm_regulator_release(struct device * dev,void * res)17 static void devm_regulator_release(struct device *dev, void *res)
18 {
19 	regulator_put(*(struct regulator **)res);
20 }
21 
_devm_regulator_get(struct device * dev,const char * id,int get_type)22 static 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  */
devm_regulator_get(struct device * dev,const char * id)51 struct regulator *devm_regulator_get(struct device *dev, const char *id)
52 {
53 	return _devm_regulator_get(dev, id, NORMAL_GET);
54 }
55 EXPORT_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  */
devm_regulator_get_exclusive(struct device * dev,const char * id)66 struct regulator *devm_regulator_get_exclusive(struct device *dev,
67 					       const char *id)
68 {
69 	return _devm_regulator_get(dev, id, EXCLUSIVE_GET);
70 }
71 EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive);
72 
regulator_action_disable(void * d)73 static void regulator_action_disable(void *d)
74 {
75 	struct regulator *r = (struct regulator *)d;
76 
77 	regulator_disable(r);
78 }
79 
_devm_regulator_get_enable(struct device * dev,const char * id,int get_type)80 static int _devm_regulator_get_enable(struct device *dev, const char *id,
81 				      int get_type)
82 {
83 	struct regulator *r;
84 	int ret;
85 
86 	r = _devm_regulator_get(dev, id, get_type);
87 	if (IS_ERR(r))
88 		return PTR_ERR(r);
89 
90 	ret = regulator_enable(r);
91 	if (!ret)
92 		ret = devm_add_action_or_reset(dev, &regulator_action_disable, r);
93 
94 	if (ret)
95 		devm_regulator_put(r);
96 
97 	return ret;
98 }
99 
100 /**
101  * devm_regulator_get_enable_optional - Resource managed regulator get and enable
102  * @dev: device to supply
103  * @id:  supply name or regulator ID.
104  *
105  * Get and enable regulator for duration of the device life-time.
106  * regulator_disable() and regulator_put() are automatically called on driver
107  * detach. See regulator_get_optional() and regulator_enable() for more
108  * information.
109  */
devm_regulator_get_enable_optional(struct device * dev,const char * id)110 int devm_regulator_get_enable_optional(struct device *dev, const char *id)
111 {
112 	return _devm_regulator_get_enable(dev, id, OPTIONAL_GET);
113 }
114 EXPORT_SYMBOL_GPL(devm_regulator_get_enable_optional);
115 
116 /**
117  * devm_regulator_get_enable - Resource managed regulator get and enable
118  * @dev: device to supply
119  * @id:  supply name or regulator ID.
120  *
121  * Get and enable regulator for duration of the device life-time.
122  * regulator_disable() and regulator_put() are automatically called on driver
123  * detach. See regulator_get() and regulator_enable() for more
124  * information.
125  */
devm_regulator_get_enable(struct device * dev,const char * id)126 int devm_regulator_get_enable(struct device *dev, const char *id)
127 {
128 	return _devm_regulator_get_enable(dev, id, NORMAL_GET);
129 }
130 EXPORT_SYMBOL_GPL(devm_regulator_get_enable);
131 
132 /**
133  * devm_regulator_get_optional - Resource managed regulator_get_optional()
134  * @dev: device to supply
135  * @id:  supply name or regulator ID.
136  *
137  * Managed regulator_get_optional(). Regulators returned from this
138  * function are automatically regulator_put() on driver detach. See
139  * regulator_get_optional() for more information.
140  */
devm_regulator_get_optional(struct device * dev,const char * id)141 struct regulator *devm_regulator_get_optional(struct device *dev,
142 					      const char *id)
143 {
144 	return _devm_regulator_get(dev, id, OPTIONAL_GET);
145 }
146 EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
147 
devm_regulator_match(struct device * dev,void * res,void * data)148 static int devm_regulator_match(struct device *dev, void *res, void *data)
149 {
150 	struct regulator **r = res;
151 	if (!r || !*r) {
152 		WARN_ON(!r || !*r);
153 		return 0;
154 	}
155 	return *r == data;
156 }
157 
158 /**
159  * devm_regulator_put - Resource managed regulator_put()
160  * @regulator: regulator to free
161  *
162  * Deallocate a regulator allocated with devm_regulator_get(). Normally
163  * this function will not need to be called and the resource management
164  * code will ensure that the resource is freed.
165  */
devm_regulator_put(struct regulator * regulator)166 void devm_regulator_put(struct regulator *regulator)
167 {
168 	int rc;
169 
170 	rc = devres_release(regulator->dev, devm_regulator_release,
171 			    devm_regulator_match, regulator);
172 	if (rc != 0)
173 		WARN_ON(rc);
174 }
175 EXPORT_SYMBOL_GPL(devm_regulator_put);
176 
177 struct regulator_bulk_devres {
178 	struct regulator_bulk_data *consumers;
179 	int num_consumers;
180 };
181 
devm_regulator_bulk_release(struct device * dev,void * res)182 static void devm_regulator_bulk_release(struct device *dev, void *res)
183 {
184 	struct regulator_bulk_devres *devres = res;
185 
186 	regulator_bulk_free(devres->num_consumers, devres->consumers);
187 }
188 
189 /**
190  * devm_regulator_bulk_get - managed get multiple regulator consumers
191  *
192  * @dev:           device to supply
193  * @num_consumers: number of consumers to register
194  * @consumers:     configuration of consumers; clients are stored here.
195  *
196  * @return 0 on success, an errno on failure.
197  *
198  * This helper function allows drivers to get several regulator
199  * consumers in one operation with management, the regulators will
200  * automatically be freed when the device is unbound.  If any of the
201  * regulators cannot be acquired then any regulators that were
202  * allocated will be freed before returning to the caller.
203  */
devm_regulator_bulk_get(struct device * dev,int num_consumers,struct regulator_bulk_data * consumers)204 int devm_regulator_bulk_get(struct device *dev, int num_consumers,
205 			    struct regulator_bulk_data *consumers)
206 {
207 	struct regulator_bulk_devres *devres;
208 	int ret;
209 
210 	devres = devres_alloc(devm_regulator_bulk_release,
211 			      sizeof(*devres), GFP_KERNEL);
212 	if (!devres)
213 		return -ENOMEM;
214 
215 	ret = regulator_bulk_get(dev, num_consumers, consumers);
216 	if (!ret) {
217 		devres->consumers = consumers;
218 		devres->num_consumers = num_consumers;
219 		devres_add(dev, devres);
220 	} else {
221 		devres_free(devres);
222 	}
223 
224 	return ret;
225 }
226 EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
227 
228 /**
229  * devm_regulator_bulk_get_const - devm_regulator_bulk_get() w/ const data
230  *
231  * @dev:           device to supply
232  * @num_consumers: number of consumers to register
233  * @in_consumers:  const configuration of consumers
234  * @out_consumers: in_consumers is copied here and this is passed to
235  *		   devm_regulator_bulk_get().
236  *
237  * This is a convenience function to allow bulk regulator configuration
238  * to be stored "static const" in files.
239  *
240  * Return: 0 on success, an errno on failure.
241  */
devm_regulator_bulk_get_const(struct device * dev,int num_consumers,const struct regulator_bulk_data * in_consumers,struct regulator_bulk_data ** out_consumers)242 int devm_regulator_bulk_get_const(struct device *dev, int num_consumers,
243 				  const struct regulator_bulk_data *in_consumers,
244 				  struct regulator_bulk_data **out_consumers)
245 {
246 	*out_consumers = devm_kmemdup(dev, in_consumers,
247 				      num_consumers * sizeof(*in_consumers),
248 				      GFP_KERNEL);
249 	if (*out_consumers == NULL)
250 		return -ENOMEM;
251 
252 	return devm_regulator_bulk_get(dev, num_consumers, *out_consumers);
253 }
254 EXPORT_SYMBOL_GPL(devm_regulator_bulk_get_const);
255 
devm_regulator_bulk_match(struct device * dev,void * res,void * data)256 static int devm_regulator_bulk_match(struct device *dev, void *res,
257 				     void *data)
258 {
259 	struct regulator_bulk_devres *match = res;
260 	struct regulator_bulk_data *target = data;
261 
262 	/*
263 	 * We check the put uses same consumer list as the get did.
264 	 * We _could_ scan all entries in consumer array and check the
265 	 * regulators match but ATM I don't see the need. We can change this
266 	 * later if needed.
267 	 */
268 	return match->consumers == target;
269 }
270 
271 /**
272  * devm_regulator_bulk_put - Resource managed regulator_bulk_put()
273  * @consumers: consumers to free
274  *
275  * Deallocate regulators allocated with devm_regulator_bulk_get(). Normally
276  * this function will not need to be called and the resource management
277  * code will ensure that the resource is freed.
278  */
devm_regulator_bulk_put(struct regulator_bulk_data * consumers)279 void devm_regulator_bulk_put(struct regulator_bulk_data *consumers)
280 {
281 	int rc;
282 	struct regulator *regulator = consumers[0].consumer;
283 
284 	rc = devres_release(regulator->dev, devm_regulator_bulk_release,
285 			    devm_regulator_bulk_match, consumers);
286 	if (rc != 0)
287 		WARN_ON(rc);
288 }
289 EXPORT_SYMBOL_GPL(devm_regulator_bulk_put);
290 
devm_regulator_bulk_disable(void * res)291 static void devm_regulator_bulk_disable(void *res)
292 {
293 	struct regulator_bulk_devres *devres = res;
294 	int i;
295 
296 	for (i = 0; i < devres->num_consumers; i++)
297 		regulator_disable(devres->consumers[i].consumer);
298 }
299 
300 /**
301  * devm_regulator_bulk_get_enable - managed get'n enable multiple regulators
302  *
303  * @dev:           device to supply
304  * @num_consumers: number of consumers to register
305  * @id:            list of supply names or regulator IDs
306  *
307  * @return 0 on success, an errno on failure.
308  *
309  * This helper function allows drivers to get several regulator
310  * consumers in one operation with management, the regulators will
311  * automatically be freed when the device is unbound.  If any of the
312  * regulators cannot be acquired then any regulators that were
313  * allocated will be freed before returning to the caller.
314  */
devm_regulator_bulk_get_enable(struct device * dev,int num_consumers,const char * const * id)315 int devm_regulator_bulk_get_enable(struct device *dev, int num_consumers,
316 				   const char * const *id)
317 {
318 	struct regulator_bulk_devres *devres;
319 	struct regulator_bulk_data *consumers;
320 	int i, ret;
321 
322 	devres = devm_kmalloc(dev, sizeof(*devres), GFP_KERNEL);
323 	if (!devres)
324 		return -ENOMEM;
325 
326 	devres->consumers = devm_kcalloc(dev, num_consumers, sizeof(*consumers),
327 					 GFP_KERNEL);
328 	consumers = devres->consumers;
329 	if (!consumers)
330 		return -ENOMEM;
331 
332 	devres->num_consumers = num_consumers;
333 
334 	for (i = 0; i < num_consumers; i++)
335 		consumers[i].supply = id[i];
336 
337 	ret = devm_regulator_bulk_get(dev, num_consumers, consumers);
338 	if (ret)
339 		return ret;
340 
341 	for (i = 0; i < num_consumers; i++) {
342 		ret = regulator_enable(consumers[i].consumer);
343 		if (ret)
344 			goto unwind;
345 	}
346 
347 	ret = devm_add_action(dev, devm_regulator_bulk_disable, devres);
348 	if (!ret)
349 		return 0;
350 
351 unwind:
352 	while (--i >= 0)
353 		regulator_disable(consumers[i].consumer);
354 
355 	devm_regulator_bulk_put(consumers);
356 
357 	return ret;
358 }
359 EXPORT_SYMBOL_GPL(devm_regulator_bulk_get_enable);
360 
devm_rdev_release(struct device * dev,void * res)361 static void devm_rdev_release(struct device *dev, void *res)
362 {
363 	regulator_unregister(*(struct regulator_dev **)res);
364 }
365 
366 /**
367  * devm_regulator_register - Resource managed regulator_register()
368  * @dev:            device to supply
369  * @regulator_desc: regulator to register
370  * @config:         runtime configuration for regulator
371  *
372  * Called by regulator drivers to register a regulator.  Returns a
373  * valid pointer to struct regulator_dev on success or an ERR_PTR() on
374  * error.  The regulator will automatically be released when the device
375  * is unbound.
376  */
devm_regulator_register(struct device * dev,const struct regulator_desc * regulator_desc,const struct regulator_config * config)377 struct regulator_dev *devm_regulator_register(struct device *dev,
378 				  const struct regulator_desc *regulator_desc,
379 				  const struct regulator_config *config)
380 {
381 	struct regulator_dev **ptr, *rdev;
382 
383 	ptr = devres_alloc(devm_rdev_release, sizeof(*ptr),
384 			   GFP_KERNEL);
385 	if (!ptr)
386 		return ERR_PTR(-ENOMEM);
387 
388 	rdev = regulator_register(dev, regulator_desc, config);
389 	if (!IS_ERR(rdev)) {
390 		*ptr = rdev;
391 		devres_add(dev, ptr);
392 	} else {
393 		devres_free(ptr);
394 	}
395 
396 	return rdev;
397 }
398 EXPORT_SYMBOL_GPL(devm_regulator_register);
399 
400 struct regulator_supply_alias_match {
401 	struct device *dev;
402 	const char *id;
403 };
404 
devm_regulator_match_supply_alias(struct device * dev,void * res,void * data)405 static int devm_regulator_match_supply_alias(struct device *dev, void *res,
406 					     void *data)
407 {
408 	struct regulator_supply_alias_match *match = res;
409 	struct regulator_supply_alias_match *target = data;
410 
411 	return match->dev == target->dev && strcmp(match->id, target->id) == 0;
412 }
413 
devm_regulator_destroy_supply_alias(struct device * dev,void * res)414 static void devm_regulator_destroy_supply_alias(struct device *dev, void *res)
415 {
416 	struct regulator_supply_alias_match *match = res;
417 
418 	regulator_unregister_supply_alias(match->dev, match->id);
419 }
420 
421 /**
422  * devm_regulator_register_supply_alias - Resource managed
423  * regulator_register_supply_alias()
424  *
425  * @dev:       device to supply
426  * @id:        supply name or regulator ID
427  * @alias_dev: device that should be used to lookup the supply
428  * @alias_id:  supply name or regulator ID that should be used to lookup the
429  * supply
430  *
431  * The supply alias will automatically be unregistered when the source
432  * device is unbound.
433  */
devm_regulator_register_supply_alias(struct device * dev,const char * id,struct device * alias_dev,const char * alias_id)434 int devm_regulator_register_supply_alias(struct device *dev, const char *id,
435 					 struct device *alias_dev,
436 					 const char *alias_id)
437 {
438 	struct regulator_supply_alias_match *match;
439 	int ret;
440 
441 	match = devres_alloc(devm_regulator_destroy_supply_alias,
442 			   sizeof(struct regulator_supply_alias_match),
443 			   GFP_KERNEL);
444 	if (!match)
445 		return -ENOMEM;
446 
447 	match->dev = dev;
448 	match->id = id;
449 
450 	ret = regulator_register_supply_alias(dev, id, alias_dev, alias_id);
451 	if (ret < 0) {
452 		devres_free(match);
453 		return ret;
454 	}
455 
456 	devres_add(dev, match);
457 
458 	return 0;
459 }
460 EXPORT_SYMBOL_GPL(devm_regulator_register_supply_alias);
461 
devm_regulator_unregister_supply_alias(struct device * dev,const char * id)462 static void devm_regulator_unregister_supply_alias(struct device *dev,
463 						   const char *id)
464 {
465 	struct regulator_supply_alias_match match;
466 	int rc;
467 
468 	match.dev = dev;
469 	match.id = id;
470 
471 	rc = devres_release(dev, devm_regulator_destroy_supply_alias,
472 			    devm_regulator_match_supply_alias, &match);
473 	if (rc != 0)
474 		WARN_ON(rc);
475 }
476 
477 /**
478  * devm_regulator_bulk_register_supply_alias - Managed register
479  * multiple aliases
480  *
481  * @dev:       device to supply
482  * @id:        list of supply names or regulator IDs
483  * @alias_dev: device that should be used to lookup the supply
484  * @alias_id:  list of supply names or regulator IDs that should be used to
485  *             lookup the supply
486  * @num_id:    number of aliases to register
487  *
488  * @return 0 on success, an errno on failure.
489  *
490  * This helper function allows drivers to register several supply
491  * aliases in one operation, the aliases will be automatically
492  * unregisters when the source device is unbound.  If any of the
493  * aliases cannot be registered any aliases that were registered
494  * will be removed before returning to the caller.
495  */
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)496 int devm_regulator_bulk_register_supply_alias(struct device *dev,
497 					      const char *const *id,
498 					      struct device *alias_dev,
499 					      const char *const *alias_id,
500 					      int num_id)
501 {
502 	int i;
503 	int ret;
504 
505 	for (i = 0; i < num_id; ++i) {
506 		ret = devm_regulator_register_supply_alias(dev, id[i],
507 							   alias_dev,
508 							   alias_id[i]);
509 		if (ret < 0)
510 			goto err;
511 	}
512 
513 	return 0;
514 
515 err:
516 	dev_err(dev,
517 		"Failed to create supply alias %s,%s -> %s,%s\n",
518 		id[i], dev_name(dev), alias_id[i], dev_name(alias_dev));
519 
520 	while (--i >= 0)
521 		devm_regulator_unregister_supply_alias(dev, id[i]);
522 
523 	return ret;
524 }
525 EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias);
526 
527 struct regulator_notifier_match {
528 	struct regulator *regulator;
529 	struct notifier_block *nb;
530 };
531 
devm_regulator_match_notifier(struct device * dev,void * res,void * data)532 static int devm_regulator_match_notifier(struct device *dev, void *res,
533 					 void *data)
534 {
535 	struct regulator_notifier_match *match = res;
536 	struct regulator_notifier_match *target = data;
537 
538 	return match->regulator == target->regulator && match->nb == target->nb;
539 }
540 
devm_regulator_destroy_notifier(struct device * dev,void * res)541 static void devm_regulator_destroy_notifier(struct device *dev, void *res)
542 {
543 	struct regulator_notifier_match *match = res;
544 
545 	regulator_unregister_notifier(match->regulator, match->nb);
546 }
547 
548 /**
549  * devm_regulator_register_notifier - Resource managed
550  * regulator_register_notifier
551  *
552  * @regulator: regulator source
553  * @nb:        notifier block
554  *
555  * The notifier will be registers under the consumer device and be
556  * automatically be unregistered when the source device is unbound.
557  */
devm_regulator_register_notifier(struct regulator * regulator,struct notifier_block * nb)558 int devm_regulator_register_notifier(struct regulator *regulator,
559 				     struct notifier_block *nb)
560 {
561 	struct regulator_notifier_match *match;
562 	int ret;
563 
564 	match = devres_alloc(devm_regulator_destroy_notifier,
565 			     sizeof(struct regulator_notifier_match),
566 			     GFP_KERNEL);
567 	if (!match)
568 		return -ENOMEM;
569 
570 	match->regulator = regulator;
571 	match->nb = nb;
572 
573 	ret = regulator_register_notifier(regulator, nb);
574 	if (ret < 0) {
575 		devres_free(match);
576 		return ret;
577 	}
578 
579 	devres_add(regulator->dev, match);
580 
581 	return 0;
582 }
583 EXPORT_SYMBOL_GPL(devm_regulator_register_notifier);
584 
585 /**
586  * devm_regulator_unregister_notifier - Resource managed
587  * regulator_unregister_notifier()
588  *
589  * @regulator: regulator source
590  * @nb:        notifier block
591  *
592  * Unregister a notifier registered with devm_regulator_register_notifier().
593  * Normally this function will not need to be called and the resource
594  * management code will ensure that the resource is freed.
595  */
devm_regulator_unregister_notifier(struct regulator * regulator,struct notifier_block * nb)596 void devm_regulator_unregister_notifier(struct regulator *regulator,
597 					struct notifier_block *nb)
598 {
599 	struct regulator_notifier_match match;
600 	int rc;
601 
602 	match.regulator = regulator;
603 	match.nb = nb;
604 
605 	rc = devres_release(regulator->dev, devm_regulator_destroy_notifier,
606 			    devm_regulator_match_notifier, &match);
607 	if (rc != 0)
608 		WARN_ON(rc);
609 }
610 EXPORT_SYMBOL_GPL(devm_regulator_unregister_notifier);
611 
regulator_irq_helper_drop(void * res)612 static void regulator_irq_helper_drop(void *res)
613 {
614 	regulator_irq_helper_cancel(&res);
615 }
616 
617 /**
618  * devm_regulator_irq_helper - resource managed registration of IRQ based
619  * regulator event/error notifier
620  *
621  * @dev:		device to which lifetime the helper's lifetime is
622  *			bound.
623  * @d:			IRQ helper descriptor.
624  * @irq:		IRQ used to inform events/errors to be notified.
625  * @irq_flags:		Extra IRQ flags to be OR'ed with the default
626  *			IRQF_ONESHOT when requesting the (threaded) irq.
627  * @common_errs:	Errors which can be flagged by this IRQ for all rdevs.
628  *			When IRQ is re-enabled these errors will be cleared
629  *			from all associated regulators
630  * @per_rdev_errs:	Optional error flag array describing errors specific
631  *			for only some of the regulators. These errors will be
632  *			or'ed with common errors. If this is given the array
633  *			should contain rdev_amount flags. Can be set to NULL
634  *			if there is no regulator specific error flags for this
635  *			IRQ.
636  * @rdev:		Array of pointers to regulators associated with this
637  *			IRQ.
638  * @rdev_amount:	Amount of regulators associated with this IRQ.
639  *
640  * Return: handle to irq_helper or an ERR_PTR() encoded error code.
641  */
devm_regulator_irq_helper(struct device * dev,const struct regulator_irq_desc * d,int irq,int irq_flags,int common_errs,int * per_rdev_errs,struct regulator_dev ** rdev,int rdev_amount)642 void *devm_regulator_irq_helper(struct device *dev,
643 				const struct regulator_irq_desc *d, int irq,
644 				int irq_flags, int common_errs,
645 				int *per_rdev_errs,
646 				struct regulator_dev **rdev, int rdev_amount)
647 {
648 	void *ptr;
649 	int ret;
650 
651 	ptr = regulator_irq_helper(dev, d, irq, irq_flags, common_errs,
652 				    per_rdev_errs, rdev, rdev_amount);
653 	if (IS_ERR(ptr))
654 		return ptr;
655 
656 	ret = devm_add_action_or_reset(dev, regulator_irq_helper_drop, ptr);
657 	if (ret)
658 		return ERR_PTR(ret);
659 
660 	return ptr;
661 }
662 EXPORT_SYMBOL_GPL(devm_regulator_irq_helper);
663