gpio: update dir_flags management
authorPatrick Delaunay <patrick.delaunay@st.com>
Mon, 13 Jan 2020 10:35:06 +0000 (11:35 +0100)
committerTom Rini <trini@konsulko.com>
Fri, 17 Apr 2020 03:06:54 +0000 (23:06 -0400)
Update the flag management in GPIO uclass: the desc->flags is always
combined with the requested flags and the GPIO descriptor is updated
for further call.

Add a function dm_gpio_get_dir_flags to get dynamically
the current dir_flags (configuration and value).

This patch prepare introduction of the dir flags support with new ops.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
drivers/gpio/gpio-uclass.c
include/asm-generic/gpio.h

index 29c8c0f57bbb8f447239112d92a8e3c8c34debd6..9550e45e6cdd244d92386ab9ab4ec7fac0928bea 100644 (file)
@@ -141,8 +141,9 @@ int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
        if (args->args_count < 2)
                return 0;
 
+       desc->flags = 0;
        if (args->args[1] & GPIO_ACTIVE_LOW)
-               desc->flags = GPIOD_ACTIVE_LOW;
+               desc->flags |= GPIOD_ACTIVE_LOW;
 
        return 0;
 }
@@ -559,6 +560,8 @@ int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
        if (ret)
                return ret;
 
+       /* combine the requested flags (for IN/OUT) and the descriptor flags */
+       flags |= desc->flags;
        ret = _dm_gpio_set_dir_flags(desc, flags);
 
        /* update the descriptor flags */
@@ -579,6 +582,26 @@ int dm_gpio_set_dir(struct gpio_desc *desc)
        return _dm_gpio_set_dir_flags(desc, desc->flags);
 }
 
+int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags)
+{
+       int ret;
+       ulong dir_flags;
+
+       ret = check_reserved(desc, "get_dir_flags");
+       if (ret)
+               return ret;
+
+       dir_flags = desc->flags;
+       /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
+       dir_flags &= ~GPIOD_IS_OUT_ACTIVE;
+       if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
+               dir_flags |= GPIOD_IS_OUT_ACTIVE;
+
+       *flags = dir_flags;
+
+       return 0;
+}
+
 /**
  * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
  * gpio:       GPIO number
@@ -849,7 +872,7 @@ static int gpio_request_tail(int ret, const char *nodename,
                debug("%s: dm_gpio_requestf failed\n", __func__);
                goto err;
        }
-       ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
+       ret = dm_gpio_set_dir_flags(desc, flags);
        if (ret) {
                debug("%s: dm_gpio_set_dir failed\n", __func__);
                goto err;
index 5686df7cece8887ac7656fe19279f5766d73d991..1329d02f873fd422b16b99f362ee16b23942bbd2 100644 (file)
@@ -592,8 +592,7 @@ int dm_gpio_set_value(const struct gpio_desc *desc, int value);
 /**
  * dm_gpio_set_dir() - Set the direction for a GPIO
  *
- * This sets up the direction according tot the provided flags. It will do
- * nothing unless the direction is actually specified.
+ * This sets up the direction according to the GPIO flags: desc->flags.
  *
  * @desc:      GPIO description containing device, offset and flags,
  *             previously returned by gpio_request_by_name()
@@ -602,11 +601,10 @@ int dm_gpio_set_value(const struct gpio_desc *desc, int value);
 int dm_gpio_set_dir(struct gpio_desc *desc);
 
 /**
- * dm_gpio_set_dir_flags() - Set direction using specific flags
+ * dm_gpio_set_dir_flags() - Set direction using description and added flags
  *
- * This is like dm_gpio_set_dir() except that the flags value is provided
- * instead of being used from desc->flags. This is needed because in many
- * cases the GPIO description does not include direction information.
+ * This sets up the direction according to the provided flags and the GPIO
+ * description (desc->flags) which include direction information.
  * Note that desc->flags is updated by this function.
  *
  * @desc:      GPIO description containing device, offset and flags,
@@ -616,6 +614,18 @@ int dm_gpio_set_dir(struct gpio_desc *desc);
  */
 int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags);
 
+/**
+ * dm_gpio_get_dir_flags() - Get direction flags
+ *
+ * read the current direction flags
+ *
+ * @desc:      GPIO description containing device, offset and flags,
+ *             previously returned by gpio_request_by_name()
+ * @flags:     place to put the used flags
+ * @return 0 if OK, -ve on error, in which case desc->flags is not updated
+ */
+int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags);
+
 /**
  * gpio_get_number() - Get the global GPIO number of a GPIO
  *