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); |
