diff options
author | Masahiro Yamada <yamada.masahiro@socionext.com> | 2016-05-01 19:36:57 +0900 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2016-05-30 09:37:47 +0200 |
commit | 8d5b5d5ce58ee1b90110f4e358eefe3c3a6b08a2 (patch) | |
tree | d91f638964d516a2a0dd7eee28e1e02f24e069b6 /drivers | |
parent | 1a695a905c18548062509178b98bc91e67510864 (diff) | |
download | linux-8d5b5d5ce58ee1b90110f4e358eefe3c3a6b08a2.tar.bz2 |
reset: add devm_reset_controller_register API
Add a device managed API for reset_controller_register().
This helps in reducing code in .remove callbacks and sometimes
dropping .remove callbacks entirely.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/reset/core.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 72b32bd15549..395dc9ce492e 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -93,6 +93,43 @@ void reset_controller_unregister(struct reset_controller_dev *rcdev) } EXPORT_SYMBOL_GPL(reset_controller_unregister); +static void devm_reset_controller_release(struct device *dev, void *res) +{ + reset_controller_unregister(*(struct reset_controller_dev **)res); +} + +/** + * devm_reset_controller_register - resource managed reset_controller_register() + * @dev: device that is registering this reset controller + * @rcdev: a pointer to the initialized reset controller device + * + * Managed reset_controller_register(). For reset controllers registered by + * this function, reset_controller_unregister() is automatically called on + * driver detach. See reset_controller_register() for more information. + */ +int devm_reset_controller_register(struct device *dev, + struct reset_controller_dev *rcdev) +{ + struct reset_controller_dev **rcdevp; + int ret; + + rcdevp = devres_alloc(devm_reset_controller_release, sizeof(*rcdevp), + GFP_KERNEL); + if (!rcdevp) + return -ENOMEM; + + ret = reset_controller_register(rcdev); + if (!ret) { + *rcdevp = rcdev; + devres_add(dev, rcdevp); + } else { + devres_free(rcdevp); + } + + return ret; +} +EXPORT_SYMBOL_GPL(devm_reset_controller_register); + /** * reset_control_reset - reset the controlled device * @rstc: reset controller |