diff options
author | Mark Brown <broonie@linaro.org> | 2013-08-31 06:58:26 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-09-16 19:27:53 -0400 |
commit | b33e46bcdc4e598d738ed12a5a7906be4e11d786 (patch) | |
tree | 11028144c3d74bc409f014660fe86aaac9600a21 | |
parent | 41c7a879d1d637c0c9731682a822b1c3162b0764 (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.txt | 1 | ||||
-rw-r--r-- | drivers/regulator/core.c | 66 | ||||
-rw-r--r-- | include/linux/regulator/driver.h | 5 |
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 | ||
287 | CLOCK | 288 | CLOCK |
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 | } |
3493 | EXPORT_SYMBOL_GPL(regulator_register); | 3493 | EXPORT_SYMBOL_GPL(regulator_register); |
3494 | 3494 | ||
3495 | static 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 | */ | ||
3510 | struct 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 | } | ||
3531 | EXPORT_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 | } |
3522 | EXPORT_SYMBOL_GPL(regulator_unregister); | 3560 | EXPORT_SYMBOL_GPL(regulator_unregister); |
3523 | 3561 | ||
3562 | static 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 | */ | ||
3580 | void 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 | } | ||
3588 | EXPORT_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 { | |||
334 | struct regulator_dev * | 334 | struct regulator_dev * |
335 | regulator_register(const struct regulator_desc *regulator_desc, | 335 | regulator_register(const struct regulator_desc *regulator_desc, |
336 | const struct regulator_config *config); | 336 | const struct regulator_config *config); |
337 | struct regulator_dev * | ||
338 | devm_regulator_register(struct device *dev, | ||
339 | const struct regulator_desc *regulator_desc, | ||
340 | const struct regulator_config *config); | ||
337 | void regulator_unregister(struct regulator_dev *rdev); | 341 | void regulator_unregister(struct regulator_dev *rdev); |
342 | void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev); | ||
338 | 343 | ||
339 | int regulator_notifier_call_chain(struct regulator_dev *rdev, | 344 | int regulator_notifier_call_chain(struct regulator_dev *rdev, |
340 | unsigned long event, void *data); | 345 | unsigned long event, void *data); |