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>
---

 drivers/gpio/gpio-uclass.c | 68 ++++++++++++++++++++++++++++++++++++++
 include/asm-generic/gpio.h | 47 ++++++++++++++++++++++++++
 2 files changed, 115 insertions(+)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 63c10f438b..6563809306 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -1077,6 +1077,74 @@ 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 ba669b65a9..af0122f304 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -657,4 +657,51 @@ int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong 
flags);
  */
 int gpio_get_number(const struct gpio_desc *desc);
 
+/**
+ * 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.
+ * 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.17.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to