aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-08-31 06:58:26 -0400
committerMark Brown <broonie@linaro.org>2013-09-16 19:27:53 -0400
commitb33e46bcdc4e598d738ed12a5a7906be4e11d786 (patch)
tree11028144c3d74bc409f014660fe86aaac9600a21
parent41c7a879d1d637c0c9731682a822b1c3162b0764 (diff)
regulator: core: Provide managed regulator registration
Many regulator drivers have a remove function that consists solely of calling regulator_unregister() so provide a devm_regulator_register() in order to allow this repeated code to be removed and help eliminate error handling code. Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--Documentation/driver-model/devres.txt1
-rw-r--r--drivers/regulator/core.c66
-rw-r--r--include/linux/regulator/driver.h5
3 files changed, 72 insertions, 0 deletions
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index fcb34a5697ea..3d9c2a766230 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -283,6 +283,7 @@ REGULATOR
283 devm_regulator_get() 283 devm_regulator_get()
284 devm_regulator_put() 284 devm_regulator_put()
285 devm_regulator_bulk_get() 285 devm_regulator_bulk_get()
286 devm_regulator_register()
286 287
287CLOCK 288CLOCK
288 devm_clk_get() 289 devm_clk_get()
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index a01b8b3b70ca..5f995d281672 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3492,6 +3492,44 @@ clean:
3492} 3492}
3493EXPORT_SYMBOL_GPL(regulator_register); 3493EXPORT_SYMBOL_GPL(regulator_register);
3494 3494
3495static void devm_rdev_release(struct device *dev, void *res)
3496{
3497 regulator_unregister(*(struct regulator_dev **)res);
3498}
3499
3500/**
3501 * devm_regulator_register - Resource managed regulator_register()
3502 * @regulator_desc: regulator to register
3503 * @config: runtime configuration for regulator
3504 *
3505 * Called by regulator drivers to register a regulator. Returns a
3506 * valid pointer to struct regulator_dev on success or an ERR_PTR() on
3507 * error. The regulator will automaticall be released when the device
3508 * is unbound.
3509 */
3510struct regulator_dev *devm_regulator_register(struct device *dev,
3511 const struct regulator_desc *regulator_desc,
3512 const struct regulator_config *config)
3513{
3514 struct regulator_dev **ptr, *rdev;
3515
3516 ptr = devres_alloc(devm_rdev_release, sizeof(*ptr),
3517 GFP_KERNEL);
3518 if (!ptr)
3519 return ERR_PTR(-ENOMEM);
3520
3521 rdev = regulator_register(regulator_desc, config);
3522 if (!IS_ERR(rdev)) {
3523 *ptr = rdev;
3524 devres_add(dev, ptr);
3525 } else {
3526 devres_free(ptr);
3527 }
3528
3529 return rdev;
3530}
3531EXPORT_SYMBOL_GPL(devm_regulator_register);
3532
3495/** 3533/**
3496 * regulator_unregister - unregister regulator 3534 * regulator_unregister - unregister regulator
3497 * @rdev: regulator to unregister 3535 * @rdev: regulator to unregister
@@ -3521,6 +3559,34 @@ void regulator_unregister(struct regulator_dev *rdev)
3521} 3559}
3522EXPORT_SYMBOL_GPL(regulator_unregister); 3560EXPORT_SYMBOL_GPL(regulator_unregister);
3523 3561
3562static int devm_rdev_match(struct device *dev, void *res, void *data)
3563{
3564 struct regulator_dev **r = res;
3565 if (!r || !*r) {
3566 WARN_ON(!r || !*r);
3567 return 0;
3568 }
3569 return *r == data;
3570}
3571
3572/**
3573 * devm_regulator_unregister - Resource managed regulator_unregister()
3574 * @regulator: regulator to free
3575 *
3576 * Unregister a regulator registered with devm_regulator_register().
3577 * Normally this function will not need to be called and the resource
3578 * management code will ensure that the resource is freed.
3579 */
3580void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev)
3581{
3582 int rc;
3583
3584 rc = devres_release(dev, devm_rdev_release, devm_rdev_match, rdev);
3585 if (rc != 0)
3586 WARN_ON(rc);
3587}
3588EXPORT_SYMBOL_GPL(devm_regulator_unregister);
3589
3524/** 3590/**
3525 * regulator_suspend_prepare - prepare regulators for system wide suspend 3591 * regulator_suspend_prepare - prepare regulators for system wide suspend
3526 * @state: system suspend state 3592 * @state: system suspend state
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 67e13aa5a478..8474c7f88745 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -334,7 +334,12 @@ struct regulator_dev {
334struct regulator_dev * 334struct regulator_dev *
335regulator_register(const struct regulator_desc *regulator_desc, 335regulator_register(const struct regulator_desc *regulator_desc,
336 const struct regulator_config *config); 336 const struct regulator_config *config);
337struct regulator_dev *
338devm_regulator_register(struct device *dev,
339 const struct regulator_desc *regulator_desc,
340 const struct regulator_config *config);
337void regulator_unregister(struct regulator_dev *rdev); 341void regulator_unregister(struct regulator_dev *rdev);
342void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev);
338 343
339int regulator_notifier_call_chain(struct regulator_dev *rdev, 344int regulator_notifier_call_chain(struct regulator_dev *rdev,
340 unsigned long event, void *data); 345 unsigned long event, void *data);