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