Re: [PATCH v5 10/16] gpio: devres: Add devm_gpiod_get_parent_array

From: Linus Walleij
Date: Tue Nov 19 2019 - 09:44:05 EST


On Mon, Nov 18, 2019 at 7:58 AM Matti Vaittinen
<matti.vaittinen@xxxxxxxxxxxxxxxxx> wrote:

> Bunch of MFD sub-devices which are instantiated by MFD do not have
> own device-tree nodes but have (for example) the GPIO consumer
> information in parent device's DT node. Add resource managed
> devm_gpiod_get_array() for such devices so that they can get the
> consumer information from parent DT while still binding the GPIO
> reservation life-time to this sub-device life time.
>
> If devm_gpiod_get_array is used as such - then unloading and then
> re-loading the child device fails as the GPIOs reserved during first
> load are not freed when driver for sub-device is unload (if parent
> stays there).
>
> Signed-off-by: Matti Vaittinen <matti.vaittinen@xxxxxxxxxxxxxxxxx>
(...)
> +static struct gpio_descs *__must_check
> +__devm_gpiod_get_array(struct device *gpiodev,
> + struct device *managed,
> + const char *con_id,
> + enum gpiod_flags flags)

I'm opposed to functions named __underscore_something()
so find a proper name for this function.
devm_gpiod_get_array_common() works if nothing else.

> @@ -292,19 +284,62 @@ struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
> if (!dr)
> return ERR_PTR(-ENOMEM);
>
> - descs = gpiod_get_array(dev, con_id, flags);
> + descs = gpiod_get_array(gpiodev, con_id, flags);
> if (IS_ERR(descs)) {
> devres_free(dr);
> return descs;
> }
>
> *dr = descs;
> - devres_add(dev, dr);
> + if (managed)
> + devres_add(managed, dr);
> + else
> + devres_add(gpiodev, dr);

So we only get managed resources if the "managed" device is
passed in.

> +/**
> + * devm_gpiod_get_array - Resource-managed gpiod_get_array()

And this function is supposed to be resource managed for sure.

> + * @dev: GPIO consumer
> + * @con_id: function within the GPIO consumer
> + * @flags: optional GPIO initialization flags
> + *
> + * Managed gpiod_get_array(). GPIO descriptors returned from this function are
> + * automatically disposed on driver detach. See gpiod_get_array() for detailed
> + * information about behavior and return values.
> + */
> +struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
> + const char *con_id,
> + enum gpiod_flags flags)
> +{
> + return __devm_gpiod_get_array(dev, NULL, con_id, flags);

So what is this? NULL?

Doesn't that mean you just removed all resource management for this
call?

Or am I reading it wrong?

Yours,
Linus Walleij