Message ID | f34765b5cb4e949c2e85415ded3d0ee7736cc97b.1576054779.git.matti.vaittinen@fi.rohmeurope.com |
---|---|
State | Not Applicable |
Headers | show |
Series | Support ROHM BD71828 PMIC | expand |
On Wed, Dec 11, 2019 at 10:47 AM Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> 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@fi.rohmeurope.com> > --- > > Changes since v5: > - renamed internal function (no __ - prefixes for Linus :] ) Thanks, as there are things happening in the GPIO subsystem I have put this one patch on an immutable branch here: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git/log/?h=ib-devm-gpiod-get-parent-array Please ask the maintainer (I guess Lee?) to pull this into wherever the rest of the patches should be merged if you want patches beyond this point to be applied for the next (v5.6) merge window, then this patch is not needed in the series. Yours, Linus Walleij
Hi dee Ho peeps! (Linus & Lee + other interested), On Mon, 2019-12-16 at 09:29 +0100, Linus Walleij wrote: > On Wed, Dec 11, 2019 at 10:47 AM Matti Vaittinen > <matti.vaittinen@fi.rohmeurope.com> 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@fi.rohmeurope.com> > > --- > > > > Changes since v5: > > - renamed internal function (no __ - prefixes for Linus :] ) > > Thanks, as there are things happening in the GPIO subsystem I > have put this one patch on an immutable branch here: > https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git/log/?h=ib-devm-gpiod-get-parent-array > > Please ask the maintainer (I guess Lee?) to pull this into wherever > the rest of the patches should be merged if you want patches beyond > this point to be applied for the next (v5.6) merge window, then this > patch is not needed in the series. I dropped the run-level support from regulator patch (for now at least). This means that I no longer have GPIO consumers needing this new API in the series. Which means two things: 1. There is no in-tree users of this new API as of now. This API has valid use-case immediately when an MFD sub-device which has no own (sub-device specific) compatible in DT wants to get the GPIO array and use devm - but I am not sure if we have any in-tree. (I checked current devm_gpiod_get_array() users and didn't see any MFD sub-devices which would have errorneously used the parent device for management - but I didn't check if there is any non-devm variant users that might benefit from this API) 2. There is no dependency from this series to the new API. So, there is two other options one can consider: 1. Drop this patch completely from the series and GPIO tree. 2. Apply it to GPIO tree only and drop it from this series (if this is still seen useful). Br, Matti
On Mon, Dec 16, 2019 at 9:59 AM Vaittinen, Matti <Matti.Vaittinen@fi.rohmeurope.com> wrote: > I dropped the run-level support from regulator patch (for now at > least). This means that I no longer have GPIO consumers needing this > new API in the series. OK I dropped it for now, we can add it when needed. Yours, Linus Walleij
diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 13046fcf0a5d..f5d3594b29b8 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -270,6 +270,7 @@ GPIO devm_gpiod_get_index() devm_gpiod_get_index_optional() devm_gpiod_get_optional() + devm_gpiod_get_parent_array() devm_gpiod_put() devm_gpiod_unhinge() devm_gpiochip_add_data() diff --git a/drivers/gpio/gpiolib-devres.c b/drivers/gpio/gpiolib-devres.c index 4421be09b960..affec50adb8d 100644 --- a/drivers/gpio/gpiolib-devres.c +++ b/drivers/gpio/gpiolib-devres.c @@ -255,19 +255,11 @@ struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev, } EXPORT_SYMBOL_GPL(devm_gpiod_get_index_optional); -/** - * devm_gpiod_get_array - Resource-managed gpiod_get_array() - * @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) +static struct gpio_descs *__must_check +devm_gpiod_get_array_common(struct device *gpiodev, + struct device *managed, + const char *con_id, + enum gpiod_flags flags) { struct gpio_descs **dr; struct gpio_descs *descs; @@ -277,19 +269,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); return descs; } + +/** + * devm_gpiod_get_array - Resource-managed gpiod_get_array() + * @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_common(dev, NULL, con_id, flags); +} EXPORT_SYMBOL_GPL(devm_gpiod_get_array); +/** + * devm_gpiod_get_parent_array - Resource-managed gpiod_get_array for subdevices + * @dev: Managed device whose parent is the GPIO consumer + * @con_id: function within the GPIO consumer + * @flags: optional GPIO initialization flags + * + * Managed gpiod_get_array() for subdevices. This function is intended to be + * used by MFD sub-devices whose GPIO bindings are in parent (MFD) device but + * whose GPIO reservation should last only for the dub-device life time. + * Returns EINVAL if no parent device is found. Rest of the behaviour and + * return values are as documented for gpiod_get_array() + */ +struct gpio_descs *__must_check +devm_gpiod_get_parent_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags) +{ + if (!dev | !dev->parent) + return ERR_PTR(-EINVAL); + return devm_gpiod_get_array_common(dev->parent, dev, con_id, flags); +} +EXPORT_SYMBOL_GPL(devm_gpiod_get_parent_array); + /** * devm_gpiod_get_array_optional - Resource-managed gpiod_get_array_optional() * @dev: GPIO consumer diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 5215fdba6b9a..ff0558492645 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -103,6 +103,11 @@ struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev, struct gpio_descs *__must_check devm_gpiod_get_array_optional(struct device *dev, const char *con_id, enum gpiod_flags flags); +struct gpio_descs *__must_check +devm_gpiod_get_parent_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags); + void devm_gpiod_put(struct device *dev, struct gpio_desc *desc); void devm_gpiod_unhinge(struct device *dev, struct gpio_desc *desc); void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs);
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@fi.rohmeurope.com> --- Changes since v5: - renamed internal function (no __ - prefixes for Linus :] ) .../driver-api/driver-model/devres.rst | 1 + drivers/gpio/gpiolib-devres.c | 65 ++++++++++++++----- include/linux/gpio/consumer.h | 5 ++ 3 files changed, 56 insertions(+), 15 deletions(-)