[PATCH v4 01/21] drivers: reset: Add devm_to_reset() to return dummy "struct reset_ctl"

Simon Glass sjg at chromium.org
Tue Jul 20 20:32:51 CEST 2021


Hi Kishon,

On Mon, 12 Jul 2021 at 00:20, Kishon Vijay Abraham I <kishon at ti.com> wrote:
>
> 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 <sjg at chromium.org>
> Signed-off-by: Kishon Vijay Abraham I <kishon at 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;

This var ends up in BSS so won't work in early SPL / pre-relocation in
U-Boot. Please add a priv_auto struct in the UCLASS_DRIVER() and put
this value in there.

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

Can this function move into the test itself? It seems strange for it to be here.

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

Can you not do:

if (ret)
    return ret;

?

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

Returns the reset_ctl to use for a devm reset?

> + *
> + * 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

Put the positive case first.

Returns @in if valid. If not valid, returns a dummy reset_ctl for
which reset_valid() will always return false.

> + * @return 0 if OK, or a negative error code.

Please document what specific errors this returns as this is important.

> + */
> +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;

That indicates success but *outp is not set. Is that OK? Should you
return -ENOSYS, or maybe set *outp to something?

> +}
>  #endif
>
>  /**
> --
> 2.17.1
>

Regards,
Simon


More information about the U-Boot mailing list