Add devm_to_reset() to return dummy "struct reset_ctl", useful for invoking reset APIs which doesn't have a valid "struct reset_ctl".
Suggested-by: Simon Glass <s...@chromium.org> Signed-off-by: Kishon Vijay Abraham I <kis...@ti.com> --- drivers/reset/reset-uclass.c | 16 ++++++++++++++++ drivers/reset/sandbox-reset-test.c | 4 +++- include/reset.h | 17 +++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c index 8caa616ed9..9f2eeb4fe4 100644 --- a/drivers/reset/reset-uclass.c +++ b/drivers/reset/reset-uclass.c @@ -15,6 +15,8 @@ #include <dm/devres.h> #include <dm/lists.h> +static struct reset_ctl devm_no_reset; + static inline struct reset_ops *reset_dev_ops(struct udevice *dev) { return (struct reset_ops *)dev->driver->ops; @@ -256,6 +258,20 @@ int reset_release_all(struct reset_ctl *reset_ctl, int count) return 0; } +int devm_to_reset(struct reset_ctl *in, struct reset_ctl **outp) +{ + if (IS_ERR_OR_NULL(in)) { + *outp = &devm_no_reset; + if (!in) + return -ENOENT; + else + return PTR_ERR(in); + } + *outp = in; + + return 0; +} + static void devm_reset_release(struct udevice *dev, void *res) { reset_free(res); diff --git a/drivers/reset/sandbox-reset-test.c b/drivers/reset/sandbox-reset-test.c index 51b79810c8..4389bde5e7 100644 --- a/drivers/reset/sandbox-reset-test.c +++ b/drivers/reset/sandbox-reset-test.c @@ -32,13 +32,15 @@ int sandbox_reset_test_get_devm(struct udevice *dev) { struct sandbox_reset_test *sbrt = dev_get_priv(dev); struct reset_ctl *r; + int ret; r = devm_reset_control_get(dev, "not-a-valid-reset-ctl"); if (!IS_ERR(r)) return -EINVAL; r = devm_reset_control_get_optional(dev, "not-a-valid-reset-ctl"); - if (r) + ret = devm_to_reset(r, &r); + if (reset_valid(r)) return -EINVAL; sbrt->ctlp = devm_reset_control_get(dev, "test"); diff --git a/include/reset.h b/include/reset.h index cde2c4b4a8..21affc1455 100644 --- a/include/reset.h +++ b/include/reset.h @@ -341,6 +341,18 @@ int reset_status(struct reset_ctl *reset_ctl); */ int reset_release_all(struct reset_ctl *reset_ctl, int count); +/** + * devm_to_reset - Provide a dummy reset_ctl for invalid reset_ctl + * + * Provide a dummy reset_ctl for invalid reset_ctl or give the same + * input reset_ctl + * + * @in: Input reset_ctl returned by devm_reset_control_get() + * @outp: Dummy reset_ctl for invalid reset_ctl or Input reset_ctl + * @return 0 if OK, or a negative error code. + */ +int devm_to_reset(struct reset_ctl *in, struct reset_ctl **outp); + /** * reset_release_bulk - Assert/Free an array of previously requested reset * signals in a reset control bulk struct. @@ -456,6 +468,11 @@ static inline int reset_release_bulk(struct reset_ctl_bulk *bulk) { return 0; } + +static inline int devm_to_reset(struct reset_ctl *in, struct reset_ctl **outp) +{ + return 0; +} #endif /** -- 2.17.1