From patchwork Mon Jan 13 10:35:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Delaunay X-Patchwork-Id: 239561 List-Id: U-Boot discussion From: patrick.delaunay at st.com (Patrick Delaunay) Date: Mon, 13 Jan 2020 11:35:06 +0100 Subject: [PATCH v3 12/21] gpio: update dir_flags management In-Reply-To: <20200113103515.20879-1-patrick.delaunay@st.com> References: <20200113103515.20879-1-patrick.delaunay@st.com> Message-ID: <20200113103515.20879-13-patrick.delaunay@st.com> 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 Reviewed-by: Simon Glass --- This patch was part of v2 08/14 = gpio: add ops for configuration with dir flags Changes in v3: - Split the previous patch [PATCH v2 08/14] to help review Changes in v2: None drivers/gpio/gpio-uclass.c | 27 +++++++++++++++++++++++++-- include/asm-generic/gpio.h | 22 ++++++++++++++++------ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 1d16d4acf9..85f0b03f81 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -140,8 +140,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; } @@ -558,6 +559,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 */ @@ -578,6 +581,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 @@ -848,7 +871,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; diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 111319f41f..3dd0002b0b 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -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 *