On 08/09/20 04:12PM, Heinrich Schuchardt wrote:
> On 08.09.20 07:40, Pratyush Yadav wrote:
> > From: Jean-Jacques Hiblot <jjhib...@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 <jjhib...@ti.com>
> > Reviewed-by: Simon Glass <s...@chromium.org>
> > Signed-off-by: Pratyush Yadav <p.ya...@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

Reply via email to