summaryrefslogtreecommitdiff
path: root/drivers/reset/core.c
diff options
context:
space:
mode:
authorMasahiro Yamada <yamada.masahiro@socionext.com>2016-05-01 13:36:57 +0300
committerPhilipp Zabel <p.zabel@pengutronix.de>2016-05-30 10:37:47 +0300
commit8d5b5d5ce58ee1b90110f4e358eefe3c3a6b08a2 (patch)
treed91f638964d516a2a0dd7eee28e1e02f24e069b6 /drivers/reset/core.c
parent1a695a905c18548062509178b98bc91e67510864 (diff)
downloadlinux-8d5b5d5ce58ee1b90110f4e358eefe3c3a6b08a2.tar.xz
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/reset/core.c')
-rw-r--r--drivers/reset/core.c37
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