[PATCH v4 1/2] drivers: gpio: Add a managed API to get a GPIO from the device-tree
Pratyush Yadav
p.yadav at ti.com
Tue Sep 8 17:15:25 CEST 2020
On 08/09/20 04:12PM, Heinrich Schuchardt wrote:
> On 08.09.20 07:40, Pratyush Yadav wrote:
> > From: Jean-Jacques Hiblot <jjhiblot at ti.com>
> >
> > Add managed functions to get a gpio from the devce-tree, based on a
> > property name (minus the '-gpios' suffix) and optionally an index.
> >
> > When the device is unbound, the GPIO is automatically released and the
> > data structure is freed.
> >
> > Signed-off-by: Jean-Jacques Hiblot <jjhiblot at ti.com>
> > Reviewed-by: Simon Glass <sjg at chromium.org>
> > Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
> > ---
> > drivers/gpio/gpio-uclass.c | 71 ++++++++++++++++++++++++++++++++++++++
> > include/asm-generic/gpio.h | 47 +++++++++++++++++++++++++
> > 2 files changed, 118 insertions(+)
> >
> > diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
> > index 9c53299b6a..0c01413b58 100644
> > --- a/drivers/gpio/gpio-uclass.c
> > +++ b/drivers/gpio/gpio-uclass.c
> > @@ -6,6 +6,8 @@
> > #include <common.h>
> > #include <dm.h>
> > #include <log.h>
> > +#include <dm/devres.h>
> > +#include <dm/device_compat.h>
> > #include <dm/device-internal.h>
> > #include <dm/lists.h>
> > #include <dm/uclass-internal.h>
> > @@ -1209,6 +1211,75 @@ int gpio_dev_request_index(struct udevice *dev, const char *nodename,
> > flags, 0, dev);
> > }
> >
> > +static void devm_gpiod_release(struct udevice *dev, void *res)
> > +{
> > + dm_gpio_free(dev, res);
> > +}
> > +
> > +static int devm_gpiod_match(struct udevice *dev, void *res, void *data)
> > +{
> > + return res == data;
> > +}
> > +
> > +struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
> > + unsigned int index, int flags)
> > +{
> > + int rc;
> > + struct gpio_desc *desc;
> > + char *propname;
> > + static const char suffix[] = "-gpios";
> > +
> > + propname = malloc(strlen(id) + sizeof(suffix));
> > + if (!propname) {
> > + rc = -ENOMEM;
> > + goto end;
> > + }
> > +
> > + strcpy(propname, id);
> > + strcat(propname, suffix);
> > +
> > + desc = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc),
> > + __GFP_ZERO);
> > + if (unlikely(!desc)) {
> > + rc = -ENOMEM;
> > + goto end;
> > + }
> > +
> > + rc = gpio_request_by_name(dev, propname, index, desc, flags);
> > +
> > +end:
> > + if (propname)
> > + free(propname);
> > +
> > + if (rc)
> > + return ERR_PTR(rc);
> > +
> > + devres_add(dev, desc);
> > +
> > + return desc;
> > +}
> > +
> > +struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
> > + const char *id,
> > + unsigned int index,
> > + int flags)
> > +{
> > + struct gpio_desc *desc = devm_gpiod_get_index(dev, id, index, flags);
> > +
> > + if (IS_ERR(desc))
> > + return NULL;
> > +
> > + return desc;
> > +}
> > +
> > +void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc)
> > +{
> > + int rc;
> > +
> > + rc = devres_release(dev, devm_gpiod_release, devm_gpiod_match, desc);
> > + WARN_ON(rc);
> > +}
> > +
> > static int gpio_post_bind(struct udevice *dev)
> > {
> > struct udevice *child;
> > diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
> > index a57dd2665c..ad6979a8ce 100644
> > --- a/include/asm-generic/gpio.h
> > +++ b/include/asm-generic/gpio.h
> > @@ -701,4 +701,51 @@ int gpio_get_number(const struct gpio_desc *desc);
> > */
> > int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio);
> >
> > +/**
> > + * devm_gpiod_get_index - Resource-managed gpiod_get()
> > + * @dev: GPIO consumer
> > + * @con_id: function within the GPIO consumer
> > + * @index: index of the GPIO to obtain in the consumer
> > + * @flags: optional GPIO initialization flags
> > + *
> > + * Managed gpiod_get(). GPIO descriptors returned from this function are
> > + * automatically disposed on driver detach.
>
> You pass in a device but write "driver detach". Shouldn't the object be
> "device" in the description as in your commit message?
Yes, it should be device.
> Devices have methods remove() and unbind() but no detach. In the commit
> message you speak of unbind(). Please, don't use alternative language.
Ok.
> Please, include the API in the HTML documentation created by 'make
> htmldocs'.
I tried searching for the GPIO API documentation under doc/ but I can't
find anything. README.gpio doesn't mention it anywhere and doc/api/ has
no file for gpio. Where do I document the newly added APIs then?
> Why did you choose the unbind() and not the remove() event for releasing
> the GPIOs?
I did not. Whoever added the devres API did (git blames Masahiro
Yamada). device_unbind() calls devres_release_all() so as a consequence
GPIO is released when the device is unbound.
> Best regards
>
> Heinrich
>
> > + * Return the GPIO descriptor corresponding to the function con_id of device
> > + * dev, -ENOENT if no GPIO has been assigned to the requested function, or
> > + * another IS_ERR() code if an error occurred while trying to acquire the GPIO.
> > + */
> > +struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
> > + unsigned int index, int flags);
> > +
> > +#define devm_gpiod_get(dev, id, flags) devm_gpiod_get_index(dev, id, 0, flags)
> > +/**
> > + * gpiod_get_optional - obtain an optional GPIO for a given GPIO function
> > + * @dev: GPIO consumer, can be NULL for system-global GPIOs
> > + * @con_id: function within the GPIO consumer
> > + * @index: index of the GPIO to obtain in the consumer
> > + * @flags: optional GPIO initialization flags
> > + *
> > + * This is equivalent to devm_gpiod_get(), except that when no GPIO was
> > + * assigned to the requested function it will return NULL. This is convenient
> > + * for drivers that need to handle optional GPIOs.
> > + */
> > +struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
> > + const char *id,
> > + unsigned int index,
> > + int flags);
> > +
> > +#define devm_gpiod_get_optional(dev, id, flags) \
> > + devm_gpiod_get_index_optional(dev, id, 0, flags)
> > +
> > +/**
> > + * devm_gpiod_put - Resource-managed gpiod_put()
> > + * @dev: GPIO consumer
> > + * @desc: GPIO descriptor to dispose of
> > + *
> > + * Dispose of a GPIO descriptor obtained with devm_gpiod_get() or
> > + * devm_gpiod_get_index(). Normally this function will not be called as the GPIO
> > + * will be disposed of by the resource management code.
> > + */
> > +void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc);
> > +
> > #endif /* _ASM_GENERIC_GPIO_H_ */
> > --
> > 2.28.0
> >
>
--
Regards,
Pratyush Yadav
Texas Instruments India
More information about the U-Boot
mailing list