All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/16] gpio: Update and simplify the uclass API
@ 2021-02-05  4:21 Simon Glass
  2021-02-05  4:21 ` [PATCH v4 01/16] gpio: Disable functions not used with of-platdata Simon Glass
                   ` (15 more replies)
  0 siblings, 16 replies; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:21 UTC (permalink / raw)
  To: u-boot

At present the GPIO uclass mirrors what was in U-Boot before driver model.
It works well in most cases but is becoming cumbersome with things like
pull-up/down and drive strength. In those cases it is easier for the
driver to deal with all the flags at one, rather than piece by piece.

In fact the current API does not officially have a method for adjusting
anything other than the direction flags. While set_dir_flags() and
get_dir_flags() do in fact support changing other flags, this is not
documented.

Secondly, set_dir_flags actually ORs the current flags with the new ones
so it is not possible to clear flags. It seems better to use a clr/set
interface (bit clear followed by OR) to provide more flexibility.

Finally, direction_input() and direction_output() are really just the same
thing as set_dir_flags(), with a different name. We currently use the
latter if available, failing back to the former. But it makes sense to
deprecate the old methods.

This series makes the above changes. Existing drivers are mostly left
alone, since they should continue to operate as is. The sandbox driver is
updated to add the required new tests and the x86 driver is switched over
to the new API.

The STM32 driver should be checked to make sure the open source/open drain
features still work as intended.

Changes in v4:
- Update dm_gpio_set_dir_flags() to clear direction flags first

Changes in v3:
- Drop the word 'direction' in comments also
- Drop 'dir' in 'GPIO dir flags' comment
- Start at BIT(31) for sandbox-specific flags
- Add a comment to sandbox_gpio_set_flags() about clearing GPIOD_EXT_HIGH
- Incorporate GPIOD_FLAGS_OUTPUT() changes from Patrick Delaunay
- Use bit 30 for GPIOD_EXT_DRIVEN
- Split out the log-category change to a separate patch
- Use bits 28, 29 for the new flags
- Assert that count parameter is within range
- Redo digit logic to be easier to understand
- Update function comment to explain the meaning of the digits
- Fix 'compare' typo

Changes in v2:
- Use set_flags() instead of update_flags()
- Fix 'provide' typo while we are here
- Make operation of set_flags() deterministic
- Swap newf and flags in sb_gpio_set_flags()

Simon Glass (16):
  gpio: Disable functions not used with of-platdata
  dm: gpio: Rename set_dir_flags() method to update_flags()
  dm: gpio: Rename get_dir_flags() method to get_flags()
  gpio: Rename dm_gpio_get_dir_flags() to dm_gpio_get_flags()
  gpio: Drop dm_gpio_set_dir()
  gpio: sandbox: Rename GPIO dir_flags to flags
  gpio: sandbox: Use a separate flag for the value
  gpio: sandbox: Fully separate pin value from output value
  gpio: sandbox: Make sandbox_gpio_set_flags() set all flags
  dm: gpio: Add a way to update flags
  gpio: Replace direction_input() and direction_output()
  gpio: Use an 'ops' variable everywhere
  gpio: x86: Drop the deprecated methods in intel_gpio
  gpio: sandbox: Track whether a GPIO is driven
  gpio: Define the log category in the uclass
  gpio: Add a way to read 3-way strapping pins

 arch/sandbox/include/asm/gpio.h           |  17 +-
 arch/x86/include/asm/intel_pinctrl_defs.h |   5 +
 drivers/gpio/gpio-uclass.c                | 243 ++++++++++++++------
 drivers/gpio/intel_gpio.c                 |  72 +++---
 drivers/gpio/sandbox.c                    | 138 +++++++----
 drivers/gpio/stm32_gpio.c                 |  17 +-
 drivers/pinctrl/pinctrl-stmfx.c           |  19 +-
 include/asm-generic/gpio.h                | 139 +++++++++--
 test/dm/gpio.c                            | 268 +++++++++++++++++++---
 9 files changed, 690 insertions(+), 228 deletions(-)

-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 01/16] gpio: Disable functions not used with of-platdata
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
@ 2021-02-05  4:21 ` Simon Glass
  2021-03-04 18:13   ` Tom Rini
  2021-02-05  4:21 ` [PATCH v4 02/16] dm: gpio: Rename set_dir_flags() method to update_flags() Simon Glass
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:21 UTC (permalink / raw)
  To: u-boot

These functions use devicetree and cannot work with of-platdata, which has
no runtime devicetree.

If they are used, the current linker error is confusing, since it talks
about missing functions in the bowels of driver model.

Avoid compiling these functions at all with of-platdata, so that a
straightforward link error points to the problem.

Series-changes; 3
- Fix 'wprl' typo

Signed-off-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

(no changes since v1)

 drivers/gpio/gpio-uclass.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index bad6b71e0c3..e84b68db772 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -1023,6 +1023,7 @@ err:
 	return ret;
 }
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
 				       int index, struct gpio_desc *desc,
 				       int flags, bool add_index)
@@ -1109,6 +1110,7 @@ int gpio_get_list_count(struct udevice *dev, const char *list_name)
 
 	return ret;
 }
+#endif /* OF_PLATDATA */
 
 int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
 {
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 02/16] dm: gpio: Rename set_dir_flags() method to update_flags()
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
  2021-02-05  4:21 ` [PATCH v4 01/16] gpio: Disable functions not used with of-platdata Simon Glass
@ 2021-02-05  4:21 ` Simon Glass
  2021-03-04 18:14   ` Tom Rini
  2021-02-05  4:21 ` [PATCH v4 03/16] dm: gpio: Rename get_dir_flags() method to get_flags() Simon Glass
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:21 UTC (permalink / raw)
  To: u-boot

The current method is a misnomer since it is also used (e.g. by stm32) to
update pull settings and open source/open drain.

Rename it and expand the documentation to cover a few more details.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

(no changes since v2)

Changes in v2:
- Use set_flags() instead of update_flags()
- Fix 'provide' typo while we are here
- Make operation of set_flags() deterministic

 drivers/gpio/gpio-uclass.c      | 16 ++++++++--------
 drivers/gpio/sandbox.c          |  6 +++---
 drivers/gpio/stm32_gpio.c       |  6 +++---
 drivers/pinctrl/pinctrl-stmfx.c |  6 +++---
 include/asm-generic/gpio.h      | 28 ++++++++++++++++++++++------
 test/dm/gpio.c                  |  8 ++++----
 6 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index e84b68db772..d59e5df4b4a 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -619,7 +619,7 @@ static int check_dir_flags(ulong flags)
 	return 0;
 }
 
-static int _dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
+static int _dm_gpio_set_flags(struct gpio_desc *desc, ulong flags)
 {
 	struct udevice *dev = desc->dev;
 	struct dm_gpio_ops *ops = gpio_get_ops(dev);
@@ -637,9 +637,9 @@ static int _dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
 		return ret;
 	}
 
-	/* GPIOD_ are directly managed by driver in set_dir_flags*/
-	if (ops->set_dir_flags) {
-		ret = ops->set_dir_flags(dev, desc->offset, flags);
+	/* GPIOD_ are directly managed by driver in set_flags */
+	if (ops->set_flags) {
+		ret = ops->set_flags(dev, desc->offset, flags);
 	} else {
 		if (flags & GPIOD_IS_OUT) {
 			ret = ops->direction_output(dev, desc->offset,
@@ -666,7 +666,7 @@ int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
 
 	/* combine the requested flags (for IN/OUT) and the descriptor flags */
 	flags |= desc->flags;
-	ret = _dm_gpio_set_dir_flags(desc, flags);
+	ret = _dm_gpio_set_flags(desc, flags);
 
 	return ret;
 }
@@ -679,7 +679,7 @@ int dm_gpio_set_dir(struct gpio_desc *desc)
 	if (ret)
 		return ret;
 
-	return _dm_gpio_set_dir_flags(desc, desc->flags);
+	return _dm_gpio_set_flags(desc, desc->flags);
 }
 
 int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags)
@@ -1307,8 +1307,8 @@ static int gpio_post_bind(struct udevice *dev)
 			ops->get_function += gd->reloc_off;
 		if (ops->xlate)
 			ops->xlate += gd->reloc_off;
-		if (ops->set_dir_flags)
-			ops->set_dir_flags += gd->reloc_off;
+		if (ops->set_flags)
+			ops->set_flags += gd->reloc_off;
 		if (ops->get_dir_flags)
 			ops->get_dir_flags += gd->reloc_off;
 
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index dc8d506e8d4..05f17928f0a 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -177,8 +177,8 @@ static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
 	return 0;
 }
 
-static int sb_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
-				 ulong flags)
+static int sb_gpio_set_flags(struct udevice *dev, unsigned int offset,
+			     ulong flags)
 {
 	ulong *dir_flags;
 
@@ -272,7 +272,7 @@ static const struct dm_gpio_ops gpio_sandbox_ops = {
 	.set_value		= sb_gpio_set_value,
 	.get_function		= sb_gpio_get_function,
 	.xlate			= sb_gpio_xlate,
-	.set_dir_flags		= sb_gpio_set_dir_flags,
+	.set_flags		= sb_gpio_set_flags,
 	.get_dir_flags		= sb_gpio_get_dir_flags,
 #if CONFIG_IS_ENABLED(ACPIGEN)
 	.get_acpi		= sb_gpio_get_acpi,
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c
index 7184db3c527..6d1bef63c36 100644
--- a/drivers/gpio/stm32_gpio.c
+++ b/drivers/gpio/stm32_gpio.c
@@ -191,8 +191,8 @@ static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset)
 	return GPIOF_FUNC;
 }
 
-static int stm32_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
-				    ulong flags)
+static int stm32_gpio_set_flags(struct udevice *dev, unsigned int offset,
+				ulong flags)
 {
 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
 	struct stm32_gpio_regs *regs = priv->regs;
@@ -270,7 +270,7 @@ static const struct dm_gpio_ops gpio_stm32_ops = {
 	.get_value		= stm32_gpio_get_value,
 	.set_value		= stm32_gpio_set_value,
 	.get_function		= stm32_gpio_get_function,
-	.set_dir_flags		= stm32_gpio_set_dir_flags,
+	.set_flags		= stm32_gpio_set_flags,
 	.get_dir_flags		= stm32_gpio_get_dir_flags,
 };
 
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c
index 7cf08dbddd1..c93c8e9eb20 100644
--- a/drivers/pinctrl/pinctrl-stmfx.c
+++ b/drivers/pinctrl/pinctrl-stmfx.c
@@ -163,8 +163,8 @@ static int stmfx_gpio_direction_output(struct udevice *dev,
 	return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 1);
 }
 
-static int stmfx_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
-				    ulong flags)
+static int stmfx_gpio_set_flags(struct udevice *dev, unsigned int offset,
+				ulong flags)
 {
 	int ret = -ENOTSUPP;
 
@@ -266,7 +266,7 @@ static const struct dm_gpio_ops stmfx_gpio_ops = {
 	.get_function = stmfx_gpio_get_function,
 	.direction_input = stmfx_gpio_direction_input,
 	.direction_output = stmfx_gpio_direction_output,
-	.set_dir_flags = stmfx_gpio_set_dir_flags,
+	.set_flags = stmfx_gpio_set_flags,
 	.get_dir_flags = stmfx_gpio_get_dir_flags,
 };
 
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 82294cbdc57..de16cabcbf9 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -301,20 +301,36 @@ struct dm_gpio_ops {
 		     struct ofnode_phandle_args *args);
 
 	/**
-	 * set_dir_flags() - Set GPIO dir flags
+	 * set_flags() - Adjust GPIO flags
 	 *
 	 * This function should set up the GPIO configuration according to the
-	 * information provide by the direction flags bitfield.
+	 * information provided by @flags.
+	 *
+	 * If any flags cannot be set (e.g. the driver or hardware does not
+	 * support them or this particular GPIO does not have the requested
+	 * feature), the driver should return -EINVAL.
+	 *
+	 * The uclass checks that flags do not obviously conflict (e.g. input
+	 * and output). If the driver finds other conflicts it should return
+	 * -ERECALLCONFLICT
+	 *
+	 * Note that GPIOD_ACTIVE_LOW should be ignored, since the uclass
+	 * adjusts for it automatically. For example, for an output GPIO,
+	 * GPIOD_ACTIVE_LOW causes GPIOD_IS_OUT_ACTIVE to be inverted by the
+	 * uclass, so the driver always sees the value that should be set at the
+	 * pin (1=high, 0=low).
 	 *
 	 * This method is optional.
 	 *
 	 * @dev:	GPIO device
 	 * @offset:	GPIO offset within that device
-	 * @flags:	GPIO configuration to use
-	 * @return 0 if OK, -ve on error
+	 * @flags:	New flags value (GPIOD_...)
+	 *
+	 * @return 0 if OK, -EINVAL if unsupported, -ERECALLCONFLICT if flags
+	 *	conflict in some *	non-obvious way and were not applied,
+	 *	other -ve on error
 	 */
-	int (*set_dir_flags)(struct udevice *dev, unsigned int offset,
-			     ulong flags);
+	int (*set_flags)(struct udevice *dev, unsigned int offset, ulong flags);
 
 	/**
 	 * get_dir_flags() - Get GPIO dir flags
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index d7b85e74ce5..36bbaedb01c 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -81,12 +81,12 @@ static int dm_test_gpio(struct unit_test_state *uts)
 	/* Make it an open drain output, and reset it */
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
 		    sandbox_gpio_get_dir_flags(dev, offset));
-	ut_assertok(ops->set_dir_flags(dev, offset,
-				       GPIOD_IS_OUT | GPIOD_OPEN_DRAIN));
+	ut_assertok(ops->set_flags(dev, offset,
+				   GPIOD_IS_OUT | GPIOD_OPEN_DRAIN));
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
 		    sandbox_gpio_get_dir_flags(dev, offset));
-	ut_assertok(ops->set_dir_flags(dev, offset,
-				       GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE));
+	ut_assertok(ops->set_flags(dev, offset,
+				   GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE));
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
 		    sandbox_gpio_get_dir_flags(dev, offset));
 
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 03/16] dm: gpio: Rename get_dir_flags() method to get_flags()
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
  2021-02-05  4:21 ` [PATCH v4 01/16] gpio: Disable functions not used with of-platdata Simon Glass
  2021-02-05  4:21 ` [PATCH v4 02/16] dm: gpio: Rename set_dir_flags() method to update_flags() Simon Glass
@ 2021-02-05  4:21 ` Simon Glass
  2021-03-04 18:14   ` Tom Rini
  2021-02-05  4:21 ` [PATCH v4 04/16] gpio: Rename dm_gpio_get_dir_flags() to dm_gpio_get_flags() Simon Glass
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:21 UTC (permalink / raw)
  To: u-boot

It is more useful to be able to read all the flags, not just the direction
ones. In fact this is what the STM32 driver does. Update the method name
to reflect this.

Tweak the docs a little and use 'flagsp' as the return argument, as is
common in driver model, to indicate it returns a value.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/gpio/gpio-uclass.c      | 30 +++++++++++++++---------------
 drivers/gpio/sandbox.c          |  8 ++++----
 drivers/gpio/stm32_gpio.c       |  8 ++++----
 drivers/pinctrl/pinctrl-stmfx.c |  8 ++++----
 include/asm-generic/gpio.h      | 11 ++++++-----
 5 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index d59e5df4b4a..c5cb9b92b36 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -682,39 +682,39 @@ int dm_gpio_set_dir(struct gpio_desc *desc)
 	return _dm_gpio_set_flags(desc, desc->flags);
 }
 
-int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags)
+int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flagsp)
 {
 	struct udevice *dev = desc->dev;
 	int ret, value;
 	struct dm_gpio_ops *ops = gpio_get_ops(dev);
-	ulong dir_flags;
+	ulong flags;
 
-	ret = check_reserved(desc, "get_dir_flags");
+	ret = check_reserved(desc, "get_flags");
 	if (ret)
 		return ret;
 
 	/* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */
-	if (ops->get_dir_flags) {
-		ret = ops->get_dir_flags(dev, desc->offset, &dir_flags);
+	if (ops->get_flags) {
+		ret = ops->get_flags(dev, desc->offset, &flags);
 		if (ret)
 			return ret;
 
 		/* GPIOD_ACTIVE_LOW is saved in desc->flags */
-		value = dir_flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
+		value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
 		if (desc->flags & GPIOD_ACTIVE_LOW)
 			value = !value;
-		dir_flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
-		dir_flags |= (desc->flags & GPIOD_ACTIVE_LOW);
+		flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
+		flags |= (desc->flags & GPIOD_ACTIVE_LOW);
 		if (value)
-			dir_flags |= GPIOD_IS_OUT_ACTIVE;
+			flags |= GPIOD_IS_OUT_ACTIVE;
 	} else {
-		dir_flags = desc->flags;
+		flags = desc->flags;
 		/* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
-		dir_flags &= ~GPIOD_IS_OUT_ACTIVE;
+		flags &= ~GPIOD_IS_OUT_ACTIVE;
 		if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
-			dir_flags |= GPIOD_IS_OUT_ACTIVE;
+			flags |= GPIOD_IS_OUT_ACTIVE;
 	}
-	*flags = dir_flags;
+	*flagsp = flags;
 
 	return 0;
 }
@@ -1309,8 +1309,8 @@ static int gpio_post_bind(struct udevice *dev)
 			ops->xlate += gd->reloc_off;
 		if (ops->set_flags)
 			ops->set_flags += gd->reloc_off;
-		if (ops->get_dir_flags)
-			ops->get_dir_flags += gd->reloc_off;
+		if (ops->get_flags)
+			ops->get_flags += gd->reloc_off;
 
 		reloc_done++;
 	}
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 05f17928f0a..38dc34ee910 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -199,11 +199,11 @@ static int sb_gpio_set_flags(struct udevice *dev, unsigned int offset,
 	return 0;
 }
 
-static int sb_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
-				 ulong *flags)
+static int sb_gpio_get_flags(struct udevice *dev, unsigned int offset,
+			     ulong *flagsp)
 {
 	debug("%s: offset:%u\n", __func__, offset);
-	*flags = *get_gpio_dir_flags(dev, offset);
+	*flagsp = *get_gpio_dir_flags(dev, offset);
 
 	return 0;
 }
@@ -273,7 +273,7 @@ static const struct dm_gpio_ops gpio_sandbox_ops = {
 	.get_function		= sb_gpio_get_function,
 	.xlate			= sb_gpio_xlate,
 	.set_flags		= sb_gpio_set_flags,
-	.get_dir_flags		= sb_gpio_get_dir_flags,
+	.get_flags		= sb_gpio_get_flags,
 #if CONFIG_IS_ENABLED(ACPIGEN)
 	.get_acpi		= sb_gpio_get_acpi,
 #endif
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c
index 6d1bef63c36..c2d7046c0dd 100644
--- a/drivers/gpio/stm32_gpio.c
+++ b/drivers/gpio/stm32_gpio.c
@@ -223,8 +223,8 @@ static int stm32_gpio_set_flags(struct udevice *dev, unsigned int offset,
 	return 0;
 }
 
-static int stm32_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
-				    ulong *flags)
+static int stm32_gpio_get_flags(struct udevice *dev, unsigned int offset,
+				ulong *flagsp)
 {
 	struct stm32_gpio_priv *priv = dev_get_priv(dev);
 	struct stm32_gpio_regs *regs = priv->regs;
@@ -259,7 +259,7 @@ static int stm32_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
 	default:
 		break;
 	}
-	*flags = dir_flags;
+	*flagsp = dir_flags;
 
 	return 0;
 }
@@ -271,7 +271,7 @@ static const struct dm_gpio_ops gpio_stm32_ops = {
 	.set_value		= stm32_gpio_set_value,
 	.get_function		= stm32_gpio_get_function,
 	.set_flags		= stm32_gpio_set_flags,
-	.get_dir_flags		= stm32_gpio_get_dir_flags,
+	.get_flags		= stm32_gpio_get_flags,
 };
 
 static int gpio_stm32_probe(struct udevice *dev)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c
index c93c8e9eb20..8ddbc3dc281 100644
--- a/drivers/pinctrl/pinctrl-stmfx.c
+++ b/drivers/pinctrl/pinctrl-stmfx.c
@@ -199,8 +199,8 @@ static int stmfx_gpio_set_flags(struct udevice *dev, unsigned int offset,
 	return ret;
 }
 
-static int stmfx_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
-				    ulong *flags)
+static int stmfx_gpio_get_flags(struct udevice *dev, unsigned int offset,
+				ulong *flagsp)
 {
 	ulong dir_flags = 0;
 	int ret;
@@ -233,7 +233,7 @@ static int stmfx_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
 				dir_flags |= GPIOD_PULL_DOWN;
 		}
 	}
-	*flags = dir_flags;
+	*flagsp = dir_flags;
 
 	return 0;
 }
@@ -267,7 +267,7 @@ static const struct dm_gpio_ops stmfx_gpio_ops = {
 	.direction_input = stmfx_gpio_direction_input,
 	.direction_output = stmfx_gpio_direction_output,
 	.set_flags = stmfx_gpio_set_flags,
-	.get_dir_flags = stmfx_gpio_get_dir_flags,
+	.get_flags = stmfx_gpio_get_flags,
 };
 
 U_BOOT_DRIVER(stmfx_gpio) = {
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index de16cabcbf9..153312d8af4 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -333,19 +333,20 @@ struct dm_gpio_ops {
 	int (*set_flags)(struct udevice *dev, unsigned int offset, ulong flags);
 
 	/**
-	 * get_dir_flags() - Get GPIO dir flags
+	 * get_flags() - Get GPIO flags
 	 *
-	 * This function return the GPIO direction flags used.
+	 * This function return the GPIO flags used. It should read this from
+	 * the hardware directly.
 	 *
 	 * This method is optional.
 	 *
 	 * @dev:	GPIO device
 	 * @offset:	GPIO offset within that device
-	 * @flags:	place to put the used direction flags by GPIO
+	 * @flagsp:	place to put the current flags value
 	 * @return 0 if OK, -ve on error
 	 */
-	int (*get_dir_flags)(struct udevice *dev, unsigned int offset,
-			     ulong *flags);
+	int (*get_flags)(struct udevice *dev, unsigned int offset,
+			 ulong *flagsp);
 
 #if CONFIG_IS_ENABLED(ACPIGEN)
 	/**
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 04/16] gpio: Rename dm_gpio_get_dir_flags() to dm_gpio_get_flags()
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (2 preceding siblings ...)
  2021-02-05  4:21 ` [PATCH v4 03/16] dm: gpio: Rename get_dir_flags() method to get_flags() Simon Glass
@ 2021-02-05  4:21 ` Simon Glass
  2021-03-04 18:14   ` Tom Rini
  2021-02-05  4:21 ` [PATCH v4 05/16] gpio: Drop dm_gpio_set_dir() Simon Glass
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:21 UTC (permalink / raw)
  To: u-boot

This function can be used to get any flags, not just direction flags.
Rename it to avoid confusion.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v3)

Changes in v3:
- Drop the word 'direction' in comments also

 drivers/gpio/gpio-uclass.c |  2 +-
 include/asm-generic/gpio.h |  6 +++---
 test/dm/gpio.c             | 12 ++++++------
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index c5cb9b92b36..87254b0781b 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -682,7 +682,7 @@ int dm_gpio_set_dir(struct gpio_desc *desc)
 	return _dm_gpio_set_flags(desc, desc->flags);
 }
 
-int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flagsp)
+int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flagsp)
 {
 	struct udevice *dev = desc->dev;
 	int ret, value;
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 153312d8af4..4f8d1938da9 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -683,16 +683,16 @@ 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
+ * dm_gpio_get_flags() - Get flags
  *
- * read the current direction flags
+ * Read the current 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);
+int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flags);
 
 /**
  * gpio_get_number() - Get the global GPIO number of a GPIO
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index 36bbaedb01c..c583d2b3447 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -397,22 +397,22 @@ static int dm_test_gpio_get_dir_flags(struct unit_test_state *uts)
 	ut_asserteq(6, gpio_request_list_by_name(dev, "test3-gpios", desc_list,
 						 ARRAY_SIZE(desc_list), 0));
 
-	ut_assertok(dm_gpio_get_dir_flags(&desc_list[0], &flags));
+	ut_assertok(dm_gpio_get_flags(&desc_list[0], &flags));
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN, flags);
 
-	ut_assertok(dm_gpio_get_dir_flags(&desc_list[1], &flags));
+	ut_assertok(dm_gpio_get_flags(&desc_list[1], &flags));
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE, flags);
 
-	ut_assertok(dm_gpio_get_dir_flags(&desc_list[2], &flags));
+	ut_assertok(dm_gpio_get_flags(&desc_list[2], &flags));
 	ut_asserteq(GPIOD_IS_OUT, flags);
 
-	ut_assertok(dm_gpio_get_dir_flags(&desc_list[3], &flags));
+	ut_assertok(dm_gpio_get_flags(&desc_list[3], &flags));
 	ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_UP, flags);
 
-	ut_assertok(dm_gpio_get_dir_flags(&desc_list[4], &flags));
+	ut_assertok(dm_gpio_get_flags(&desc_list[4], &flags));
 	ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_DOWN, flags);
 
-	ut_assertok(dm_gpio_get_dir_flags(&desc_list[5], &flags));
+	ut_assertok(dm_gpio_get_flags(&desc_list[5], &flags));
 	ut_asserteq(GPIOD_IS_IN, flags);
 
 	ut_assertok(gpio_free_list(dev, desc_list, 6));
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 05/16] gpio: Drop dm_gpio_set_dir()
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (3 preceding siblings ...)
  2021-02-05  4:21 ` [PATCH v4 04/16] gpio: Rename dm_gpio_get_dir_flags() to dm_gpio_get_flags() Simon Glass
@ 2021-02-05  4:21 ` Simon Glass
  2021-03-03 20:39   ` Tom Rini
  2021-02-05  4:21 ` [PATCH v4 06/16] gpio: sandbox: Rename GPIO dir_flags to flags Simon Glass
                   ` (10 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:21 UTC (permalink / raw)
  To: u-boot

This function is not used. Drop it.

Signed-off-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

(no changes since v1)

 drivers/gpio/gpio-uclass.c | 11 -----------
 include/asm-generic/gpio.h | 11 -----------
 2 files changed, 22 deletions(-)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 87254b0781b..8931c420845 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -671,17 +671,6 @@ int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
 	return ret;
 }
 
-int dm_gpio_set_dir(struct gpio_desc *desc)
-{
-	int ret;
-
-	ret = check_reserved(desc, "set_dir");
-	if (ret)
-		return ret;
-
-	return _dm_gpio_set_flags(desc, desc->flags);
-}
-
 int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flagsp)
 {
 	struct udevice *dev = desc->dev;
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 4f8d1938da9..f7f10c469c0 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -657,17 +657,6 @@ int dm_gpio_get_value(const struct gpio_desc *desc);
 
 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 to the GPIO flags: desc->flags.
- *
- * @desc:	GPIO description containing device, offset and flags,
- *		previously returned by gpio_request_by_name()
- * @return 0 if OK, -ve on error
- */
-int dm_gpio_set_dir(struct gpio_desc *desc);
-
 /**
  * dm_gpio_set_dir_flags() - Set direction using description and added flags
  *
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 06/16] gpio: sandbox: Rename GPIO dir_flags to flags
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (4 preceding siblings ...)
  2021-02-05  4:21 ` [PATCH v4 05/16] gpio: Drop dm_gpio_set_dir() Simon Glass
@ 2021-02-05  4:21 ` Simon Glass
  2021-03-04 18:14   ` Tom Rini
  2021-02-05  4:22 ` [PATCH v4 07/16] gpio: sandbox: Use a separate flag for the value Simon Glass
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:21 UTC (permalink / raw)
  To: u-boot

Adjust the terminology in this driver to reflect that fact that all flags
are handled, not just direction flags.

Create a new access function to get the full GPIO state, not just the
direction flags. Drop the static invalid_dir_flags since we can rely on a
segfault if something is wrong.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

(no changes since v3)

Changes in v3:
- Drop 'dir' in 'GPIO dir flags' comment

Changes in v2:
- Swap newf and flags in sb_gpio_set_flags()

 arch/sandbox/include/asm/gpio.h |  8 ++---
 drivers/gpio/sandbox.c          | 60 +++++++++++++++++++--------------
 test/dm/gpio.c                  | 18 +++++-----
 3 files changed, 47 insertions(+), 39 deletions(-)

diff --git a/arch/sandbox/include/asm/gpio.h b/arch/sandbox/include/asm/gpio.h
index df4ba4fb5f3..20d78296551 100644
--- a/arch/sandbox/include/asm/gpio.h
+++ b/arch/sandbox/include/asm/gpio.h
@@ -69,17 +69,17 @@ int sandbox_gpio_set_direction(struct udevice *dev, unsigned int offset,
  * @param offset	GPIO offset within bank
  * @return dir_flags: bitfield accesses by GPIOD_ defines
  */
-ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset);
+ulong sandbox_gpio_get_flags(struct udevice *dev, unsigned int offset);
 
 /**
  * Set the simulated flags of a GPIO (used only in sandbox test code)
  *
  * @param dev		device to use
  * @param offset	GPIO offset within bank
- * @param flags		dir_flags: bitfield accesses by GPIOD_ defines
+ * @param flags		bitfield accesses by GPIOD_ defines
  * @return -1 on error, 0 if ok
  */
-int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
-			       ulong flags);
+int sandbox_gpio_set_flags(struct udevice *dev, unsigned int offset,
+			   ulong flags);
 
 #endif
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 38dc34ee910..6f2eed50bf1 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -22,34 +22,44 @@
 
 struct gpio_state {
 	const char *label;	/* label given by requester */
-	ulong dir_flags;	/* dir_flags (GPIOD_...) */
+	ulong flags;		/* flags (GPIOD_...) */
 };
 
-/* Access routines for GPIO dir flags */
-static ulong *get_gpio_dir_flags(struct udevice *dev, unsigned int offset)
+/* Access routines for GPIO info */
+static struct gpio_state *get_gpio_state(struct udevice *dev, uint offset)
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct gpio_state *state = dev_get_priv(dev);
 
 	if (offset >= uc_priv->gpio_count) {
-		static ulong invalid_dir_flags;
 		printf("sandbox_gpio: error: invalid gpio %u\n", offset);
-		return &invalid_dir_flags;
+		return NULL;
 	}
 
-	return &state[offset].dir_flags;
+	return &state[offset];
+}
+
+/* Access routines for GPIO flags */
+static ulong *get_gpio_flags(struct udevice *dev, unsigned int offset)
+{
+	struct gpio_state *state = get_gpio_state(dev, offset);
+
+	if (!state)
+		return NULL;
+
+	return &state->flags;
 
 }
 
 static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag)
 {
-	return (*get_gpio_dir_flags(dev, offset) & flag) != 0;
+	return (*get_gpio_flags(dev, offset) & flag) != 0;
 }
 
 static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
 			 int value)
 {
-	ulong *gpio = get_gpio_dir_flags(dev, offset);
+	ulong *gpio = get_gpio_flags(dev, offset);
 
 	if (value)
 		*gpio |= flag;
@@ -88,15 +98,14 @@ int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output)
 	return 0;
 }
 
-ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset)
+ulong sandbox_gpio_get_flags(struct udevice *dev, uint offset)
 {
-	return *get_gpio_dir_flags(dev, offset);
+	return *get_gpio_flags(dev, offset);
 }
 
-int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
-			       ulong flags)
+int sandbox_gpio_set_flags(struct udevice *dev, uint offset, ulong flags)
 {
-	*get_gpio_dir_flags(dev, offset) = flags;
+	*get_gpio_flags(dev, offset) = flags;
 
 	return 0;
 }
@@ -180,30 +189,29 @@ static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
 static int sb_gpio_set_flags(struct udevice *dev, unsigned int offset,
 			     ulong flags)
 {
-	ulong *dir_flags;
+	ulong *newf;
 
-	debug("%s: offset:%u, dir_flags = %lx\n", __func__, offset, flags);
+	debug("%s: offset:%u, flags = %lx\n", __func__, offset, flags);
 
-	dir_flags = get_gpio_dir_flags(dev, offset);
+	newf = get_gpio_flags(dev, offset);
 
 	/*
 	 * For testing purposes keep the output value when switching to input.
 	 * This allows us to manipulate the input value via the gpio command.
 	 */
 	if (flags & GPIOD_IS_IN)
-		*dir_flags = (flags & ~GPIOD_IS_OUT_ACTIVE) |
-			     (*dir_flags & GPIOD_IS_OUT_ACTIVE);
+		*newf = (flags & ~GPIOD_IS_OUT_ACTIVE) |
+			(*newf & GPIOD_IS_OUT_ACTIVE);
 	else
-		*dir_flags = flags;
+		*newf = flags;
 
 	return 0;
 }
 
-static int sb_gpio_get_flags(struct udevice *dev, unsigned int offset,
-			     ulong *flagsp)
+static int sb_gpio_get_flags(struct udevice *dev, uint offset, ulong *flagsp)
 {
 	debug("%s: offset:%u\n", __func__, offset);
-	*flagsp = *get_gpio_dir_flags(dev, offset);
+	*flagsp = *get_gpio_flags(dev, offset);
 
 	return 0;
 }
@@ -456,7 +464,7 @@ static const char *sb_pinctrl_get_pin_name(struct udevice *dev,
 	return pin_name;
 }
 
-static char *get_dir_flags_string(ulong flags)
+static char *get_flags_string(ulong flags)
 {
 	if (flags & GPIOD_OPEN_DRAIN)
 		return "drive-open-drain";
@@ -475,7 +483,7 @@ static int sb_pinctrl_get_pin_muxing(struct udevice *dev,
 {
 	struct udevice *gpio_dev;
 	unsigned int gpio_idx;
-	ulong dir_flags;
+	ulong flags;
 	int function;
 
 	/* look up for the bank which owns the requested pin */
@@ -484,11 +492,11 @@ static int sb_pinctrl_get_pin_muxing(struct udevice *dev,
 		snprintf(buf, size, "Error");
 	} else {
 		function = sb_gpio_get_function(gpio_dev, gpio_idx);
-		dir_flags = *get_gpio_dir_flags(gpio_dev, gpio_idx);
+		flags = *get_gpio_flags(gpio_dev, gpio_idx);
 
 		snprintf(buf, size, "gpio %s %s",
 			 function == GPIOF_OUTPUT ? "output" : "input",
-			 get_dir_flags_string(dir_flags));
+			 get_flags_string(flags));
 	}
 
 	return 0;
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index c583d2b3447..dfbb634bf71 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -80,15 +80,15 @@ static int dm_test_gpio(struct unit_test_state *uts)
 
 	/* Make it an open drain output, and reset it */
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
-		    sandbox_gpio_get_dir_flags(dev, offset));
+		    sandbox_gpio_get_flags(dev, offset));
 	ut_assertok(ops->set_flags(dev, offset,
 				   GPIOD_IS_OUT | GPIOD_OPEN_DRAIN));
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
-		    sandbox_gpio_get_dir_flags(dev, offset));
+		    sandbox_gpio_get_flags(dev, offset));
 	ut_assertok(ops->set_flags(dev, offset,
 				   GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE));
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
-		    sandbox_gpio_get_dir_flags(dev, offset));
+		    sandbox_gpio_get_flags(dev, offset));
 
 	/* Make it an input */
 	ut_assertok(ops->direction_input(dev, offset));
@@ -176,7 +176,7 @@ static int dm_test_gpio_opendrain_opensource(struct unit_test_state *uts)
 
 	/* GPIO 0 is (GPIO_OUT|GPIO_OPEN_DRAIN) */
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
-		    sandbox_gpio_get_dir_flags(gpio_c, 0));
+		    sandbox_gpio_get_flags(gpio_c, 0));
 
 	/* Set it as output high, should become an input */
 	ut_assertok(dm_gpio_set_value(&desc_list[0], 1));
@@ -190,7 +190,7 @@ static int dm_test_gpio_opendrain_opensource(struct unit_test_state *uts)
 
 	/* GPIO 1 is (GPIO_OUT|GPIO_OPEN_SOURCE) */
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
-		    sandbox_gpio_get_dir_flags(gpio_c, 1));
+		    sandbox_gpio_get_flags(gpio_c, 1));
 
 	/* Set it as output high, should become output high */
 	ut_assertok(dm_gpio_set_value(&desc_list[1], 1));
@@ -204,7 +204,7 @@ static int dm_test_gpio_opendrain_opensource(struct unit_test_state *uts)
 
 	/* GPIO 6 is (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_DRAIN) */
 	ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
-		    sandbox_gpio_get_dir_flags(gpio_c, 6));
+		    sandbox_gpio_get_flags(gpio_c, 6));
 
 	/* Set it as output high, should become output low */
 	ut_assertok(dm_gpio_set_value(&desc_list[6], 1));
@@ -218,7 +218,7 @@ static int dm_test_gpio_opendrain_opensource(struct unit_test_state *uts)
 
 	/* GPIO 7 is (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_SOURCE) */
 	ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
-		    sandbox_gpio_get_dir_flags(gpio_c, 7));
+		    sandbox_gpio_get_flags(gpio_c, 7));
 
 	/* Set it as output high, should become an input */
 	ut_assertok(dm_gpio_set_value(&desc_list[7], 1));
@@ -363,12 +363,12 @@ static int dm_test_gpio_phandles(struct unit_test_state *uts)
 	ut_assertok(gpio_free_list(dev, desc_list, 3));
 
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
-		    sandbox_gpio_get_dir_flags(gpio_a, 1));
+		    sandbox_gpio_get_flags(gpio_a, 1));
 	ut_asserteq(6, gpio_request_list_by_name(dev, "test2-gpios", desc_list,
 						 ARRAY_SIZE(desc_list), 0));
 
 	/* This was set to output previously but flags resetted to 0 = INPUT */
-	ut_asserteq(0, sandbox_gpio_get_dir_flags(gpio_a, 1));
+	ut_asserteq(0, sandbox_gpio_get_flags(gpio_a, 1));
 	ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 1, NULL));
 
 	/* Active low should invert the input value */
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 07/16] gpio: sandbox: Use a separate flag for the value
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (5 preceding siblings ...)
  2021-02-05  4:21 ` [PATCH v4 06/16] gpio: sandbox: Rename GPIO dir_flags to flags Simon Glass
@ 2021-02-05  4:22 ` Simon Glass
  2021-03-04 18:14   ` Tom Rini
  2021-02-05  4:22 ` [PATCH v4 08/16] gpio: sandbox: Fully separate pin value from output value Simon Glass
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:22 UTC (permalink / raw)
  To: u-boot

At present with the sandbox GPIO driver it is not possible to change the
value of GPIOD_IS_OUT_ACTIVE unless the GPIO is an output. This makes it
hard to test changing the flags since we need to be aware of the internal
workings of the driver.

The feature is designed to aid testing.

Split this feature out into a separate sandbox-specific flag, so that the
flags can change unimpeded. This will make it easier to allow updating the
flags in a future patch.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

(no changes since v3)

Changes in v3:
- Start at BIT(31) for sandbox-specific flags
- Add a comment to sandbox_gpio_set_flags() about clearing GPIOD_EXT_HIGH

 arch/sandbox/include/asm/gpio.h |  5 ++++
 drivers/gpio/sandbox.c          | 47 +++++++++++++++++----------------
 2 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/arch/sandbox/include/asm/gpio.h b/arch/sandbox/include/asm/gpio.h
index 20d78296551..74d7a4cd959 100644
--- a/arch/sandbox/include/asm/gpio.h
+++ b/arch/sandbox/include/asm/gpio.h
@@ -23,6 +23,11 @@
  */
 #include <asm-generic/gpio.h>
 
+/* Our own private GPIO flags, which musn't conflict with GPIOD_... */
+#define GPIOD_EXT_HIGH		BIT(31)	/* external source is high (else low) */
+
+#define GPIOD_SANDBOX_MASK	BIT(31)
+
 /**
  * Return the simulated value of a GPIO (used only in sandbox test code)
  *
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 6f2eed50bf1..4d73b954b26 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -59,12 +59,12 @@ static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag)
 static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
 			 int value)
 {
-	ulong *gpio = get_gpio_flags(dev, offset);
+	struct gpio_state *state = get_gpio_state(dev, offset);
 
 	if (value)
-		*gpio |= flag;
+		state->flags |= flag;
 	else
-		*gpio &= ~flag;
+		state->flags &= ~flag;
 
 	return 0;
 }
@@ -75,14 +75,19 @@ static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
 
 int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
 {
+	struct gpio_state *state = get_gpio_state(dev, offset);
+
 	if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
 		debug("sandbox_gpio: get_value on output gpio %u\n", offset);
-	return get_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE);
+
+	return state->flags & GPIOD_EXT_HIGH ? true : false;
 }
 
 int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
 {
-	return set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE, value);
+	set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE | GPIOD_EXT_HIGH, value);
+
+	return 0;
 }
 
 int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
@@ -93,19 +98,29 @@ int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
 int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output)
 {
 	set_gpio_flag(dev, offset, GPIOD_IS_OUT, output);
-	set_gpio_flag(dev, offset, GPIOD_IS_IN, !(output));
+	set_gpio_flag(dev, offset, GPIOD_IS_IN, !output);
 
 	return 0;
 }
 
 ulong sandbox_gpio_get_flags(struct udevice *dev, uint offset)
 {
-	return *get_gpio_flags(dev, offset);
+	ulong flags = *get_gpio_flags(dev, offset);
+
+	return flags & ~GPIOD_SANDBOX_MASK;
 }
 
 int sandbox_gpio_set_flags(struct udevice *dev, uint offset, ulong flags)
 {
-	*get_gpio_flags(dev, offset) = flags;
+	struct gpio_state *state = get_gpio_state(dev, offset);
+
+	/*
+	 * We don't need to clear GPIOD_EXT_HIGH here to make the tests pass,
+	 * but this is handled in a future patch.
+	 */
+	if (flags & GPIOD_IS_OUT_ACTIVE)
+		flags |= GPIOD_EXT_HIGH;
+	state->flags = (state->flags & GPIOD_SANDBOX_MASK) | flags;
 
 	return 0;
 }
@@ -189,23 +204,9 @@ static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
 static int sb_gpio_set_flags(struct udevice *dev, unsigned int offset,
 			     ulong flags)
 {
-	ulong *newf;
-
 	debug("%s: offset:%u, flags = %lx\n", __func__, offset, flags);
 
-	newf = get_gpio_flags(dev, offset);
-
-	/*
-	 * For testing purposes keep the output value when switching to input.
-	 * This allows us to manipulate the input value via the gpio command.
-	 */
-	if (flags & GPIOD_IS_IN)
-		*newf = (flags & ~GPIOD_IS_OUT_ACTIVE) |
-			(*newf & GPIOD_IS_OUT_ACTIVE);
-	else
-		*newf = flags;
-
-	return 0;
+	return sandbox_gpio_set_flags(dev, offset, flags);
 }
 
 static int sb_gpio_get_flags(struct udevice *dev, uint offset, ulong *flagsp)
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 08/16] gpio: sandbox: Fully separate pin value from output value
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (6 preceding siblings ...)
  2021-02-05  4:22 ` [PATCH v4 07/16] gpio: sandbox: Use a separate flag for the value Simon Glass
@ 2021-02-05  4:22 ` Simon Glass
  2021-03-04 18:14   ` Tom Rini
  2021-02-05  4:22 ` [PATCH v4 09/16] gpio: sandbox: Make sandbox_gpio_set_flags() set all flags Simon Glass
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:22 UTC (permalink / raw)
  To: u-boot

At present we have the concept of a pin's external value. This is what
is used when getting the value of a pin. But we still set the
GPIOD_IS_OUT_ACTIVE flag when changing the value. This is not actually
correct, since if the pin changes from output to input, the external
value need not change. Adjust the logic for this difference.

Signed-off-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

(no changes since v1)

 drivers/gpio/sandbox.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 4d73b954b26..912c333e560 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -85,7 +85,7 @@ int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
 
 int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
 {
-	set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE | GPIOD_EXT_HIGH, value);
+	set_gpio_flag(dev, offset, GPIOD_EXT_HIGH, value);
 
 	return 0;
 }
@@ -141,10 +141,19 @@ static int sb_gpio_direction_input(struct udevice *dev, unsigned offset)
 static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
 				    int value)
 {
+	int ret;
+
 	debug("%s: offset:%u, value = %d\n", __func__, offset, value);
 
-	return sandbox_gpio_set_direction(dev, offset, 1) |
-		sandbox_gpio_set_value(dev, offset, value);
+	ret = sandbox_gpio_set_direction(dev, offset, 1);
+	if (ret)
+		return ret;
+	ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE | GPIOD_EXT_HIGH,
+			    value);
+	if (ret)
+		return ret;
+
+	return 0;
 }
 
 /* read GPIO IN value of port 'offset' */
@@ -158,6 +167,8 @@ static int sb_gpio_get_value(struct udevice *dev, unsigned offset)
 /* write GPIO OUT value to port 'offset' */
 static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
 {
+	int ret;
+
 	debug("%s: offset:%u, value = %d\n", __func__, offset, value);
 
 	if (!sandbox_gpio_get_direction(dev, offset)) {
@@ -166,7 +177,12 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
 		return -1;
 	}
 
-	return sandbox_gpio_set_value(dev, offset, value);
+	ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE | GPIOD_EXT_HIGH,
+			    value);
+	if (ret)
+		return ret;
+
+	return 0;
 }
 
 static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 09/16] gpio: sandbox: Make sandbox_gpio_set_flags() set all flags
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (7 preceding siblings ...)
  2021-02-05  4:22 ` [PATCH v4 08/16] gpio: sandbox: Fully separate pin value from output value Simon Glass
@ 2021-02-05  4:22 ` Simon Glass
  2021-03-04 18:14   ` Tom Rini
  2021-02-05  4:22 ` [PATCH v4 10/16] dm: gpio: Add a way to update flags Simon Glass
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:22 UTC (permalink / raw)
  To: u-boot

Allow this function to see all flags, including the internal sandbox ones.
This allows the tests to fully control the behaviour of the driver.

To make this work, move the setting of GPIOD_EXT_HIGH -to where the flags
are updated via driver model, rather than the sandbox 'back door'.

Signed-off-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

(no changes since v1)

 drivers/gpio/sandbox.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 912c333e560..d1e561ab5e6 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -114,13 +114,7 @@ int sandbox_gpio_set_flags(struct udevice *dev, uint offset, ulong flags)
 {
 	struct gpio_state *state = get_gpio_state(dev, offset);
 
-	/*
-	 * We don't need to clear GPIOD_EXT_HIGH here to make the tests pass,
-	 * but this is handled in a future patch.
-	 */
-	if (flags & GPIOD_IS_OUT_ACTIVE)
-		flags |= GPIOD_EXT_HIGH;
-	state->flags = (state->flags & GPIOD_SANDBOX_MASK) | flags;
+	state->flags = flags;
 
 	return 0;
 }
@@ -221,14 +215,23 @@ static int sb_gpio_set_flags(struct udevice *dev, unsigned int offset,
 			     ulong flags)
 {
 	debug("%s: offset:%u, flags = %lx\n", __func__, offset, flags);
+	struct gpio_state *state = get_gpio_state(dev, offset);
 
-	return sandbox_gpio_set_flags(dev, offset, flags);
+	if (flags & GPIOD_IS_OUT) {
+		if (flags & GPIOD_IS_OUT_ACTIVE)
+			flags |= GPIOD_EXT_HIGH;
+		else
+			flags &= ~GPIOD_EXT_HIGH;
+	}
+	state->flags = flags;
+
+	return 0;
 }
 
 static int sb_gpio_get_flags(struct udevice *dev, uint offset, ulong *flagsp)
 {
 	debug("%s: offset:%u\n", __func__, offset);
-	*flagsp = *get_gpio_flags(dev, offset);
+	*flagsp = *get_gpio_flags(dev, offset) & ~GPIOD_SANDBOX_MASK;
 
 	return 0;
 }
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 10/16] dm: gpio: Add a way to update flags
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (8 preceding siblings ...)
  2021-02-05  4:22 ` [PATCH v4 09/16] gpio: sandbox: Make sandbox_gpio_set_flags() set all flags Simon Glass
@ 2021-02-05  4:22 ` Simon Glass
  2021-02-08  9:00   ` Köry Maincent
                     ` (2 more replies)
  2021-02-05  4:22 ` [PATCH v4 11/16] gpio: Replace direction_input() and direction_output() Simon Glass
                   ` (5 subsequent siblings)
  15 siblings, 3 replies; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:22 UTC (permalink / raw)
  To: u-boot

It is convenient to be able to adjust some of the flags for a GPIO while
leaving others alone. Add a function for this.

Update dm_gpio_set_dir_flags() to make use of this.

Also update dm_gpio_set_value() to use this also, since this allows the
open-drain / open-source features to be implemented directly in the
driver, rather than using the uclass workaround.

Update the sandbox tests accordingly. This involves a lot of changes to
dm_test_gpio_opendrain_opensource() since we no-longer have the direciion
being reported differently depending on the open drain/open source flags.

Also update the STM32 drivers to let the uclass handle the active low/high
logic.

Drop the GPIOD_FLAGS_OUTPUT() macro which is no-longer used.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v4:
- Update dm_gpio_set_dir_flags() to clear direction flags first

Changes in v3:
- Incorporate GPIOD_FLAGS_OUTPUT() changes from Patrick Delaunay

 drivers/gpio/gpio-uclass.c      |  75 ++++++++++++++----
 drivers/gpio/stm32_gpio.c       |   3 +-
 drivers/pinctrl/pinctrl-stmfx.c |   5 +-
 include/asm-generic/gpio.h      |  31 ++++++--
 test/dm/gpio.c                  | 132 ++++++++++++++++++++++++++++----
 5 files changed, 203 insertions(+), 43 deletions(-)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 8931c420845..daaa1401087 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -568,6 +568,7 @@ int dm_gpio_get_value(const struct gpio_desc *desc)
 
 int dm_gpio_set_value(const struct gpio_desc *desc, int value)
 {
+	const struct dm_gpio_ops *ops;
 	int ret;
 
 	ret = check_reserved(desc, "set_value");
@@ -577,21 +578,33 @@ int dm_gpio_set_value(const struct gpio_desc *desc, int value)
 	if (desc->flags & GPIOD_ACTIVE_LOW)
 		value = !value;
 
+	/* GPIOD_ are directly managed by driver in set_flags */
+	ops = gpio_get_ops(desc->dev);
+	if (ops->set_flags) {
+		ulong flags = desc->flags;
+
+		if (value)
+			flags |= GPIOD_IS_OUT_ACTIVE;
+		else
+			flags &= ~GPIOD_IS_OUT_ACTIVE;
+		return ops->set_flags(desc->dev, desc->offset, flags);
+	}
+
 	/*
 	 * Emulate open drain by not actively driving the line high or
 	 * Emulate open source by not actively driving the line low
 	 */
 	if ((desc->flags & GPIOD_OPEN_DRAIN && value) ||
 	    (desc->flags & GPIOD_OPEN_SOURCE && !value))
-		return gpio_get_ops(desc->dev)->direction_input(desc->dev,
-								desc->offset);
+		return ops->direction_input(desc->dev, desc->offset);
 	else if (desc->flags & GPIOD_OPEN_DRAIN ||
 		 desc->flags & GPIOD_OPEN_SOURCE)
-		return gpio_get_ops(desc->dev)->direction_output(desc->dev,
-								desc->offset,
-								value);
+		return ops->direction_output(desc->dev, desc->offset, value);
+
+	ret = ops->set_value(desc->dev, desc->offset, value);
+	if (ret)
+		return ret;
 
-	gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
 	return 0;
 }
 
@@ -619,6 +632,17 @@ static int check_dir_flags(ulong flags)
 	return 0;
 }
 
+/**
+ * _dm_gpio_set_flags() - Send flags to the driver
+ *
+ * This uses the best available method to send the given flags to the driver.
+ * Note that if flags & GPIOD_ACTIVE_LOW, the driver sees the opposite value
+ * of GPIOD_IS_OUT_ACTIVE.
+ *
+ * @desc:	GPIO description
+ * @flags:	flags value to set
+ * @return 0 if OK, -ve on error
+ */
 static int _dm_gpio_set_flags(struct gpio_desc *desc, ulong flags)
 {
 	struct udevice *dev = desc->dev;
@@ -637,38 +661,52 @@ static int _dm_gpio_set_flags(struct gpio_desc *desc, ulong flags)
 		return ret;
 	}
 
+	/* If active low, invert the output state */
+	if ((flags & (GPIOD_IS_OUT | GPIOD_ACTIVE_LOW)) ==
+		(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW))
+		flags ^= GPIOD_IS_OUT_ACTIVE;
+
 	/* GPIOD_ are directly managed by driver in set_flags */
 	if (ops->set_flags) {
 		ret = ops->set_flags(dev, desc->offset, flags);
 	} else {
 		if (flags & GPIOD_IS_OUT) {
-			ret = ops->direction_output(dev, desc->offset,
-						    GPIOD_FLAGS_OUTPUT(flags));
+			bool value = flags & GPIOD_IS_OUT_ACTIVE;
+
+			ret = ops->direction_output(dev, desc->offset, value);
 		} else if (flags & GPIOD_IS_IN) {
 			ret = ops->direction_input(dev, desc->offset);
 		}
 	}
 
-	/* save the flags also in descriptor */
-	if (!ret)
-		desc->flags = flags;
-
 	return ret;
 }
 
-int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
+int dm_gpio_clrset_flags(struct gpio_desc *desc, ulong clr, ulong set)
 {
+	ulong flags;
 	int ret;
 
 	ret = check_reserved(desc, "set_dir_flags");
 	if (ret)
 		return ret;
 
-	/* combine the requested flags (for IN/OUT) and the descriptor flags */
-	flags |= desc->flags;
+	flags = (desc->flags & ~clr) | set;
+
 	ret = _dm_gpio_set_flags(desc, flags);
+	if (ret)
+		return ret;
 
-	return ret;
+	/* save the flags also in descriptor */
+	desc->flags = flags;
+
+	return 0;
+}
+
+int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
+{
+	/* combine the requested flags (for IN/OUT) and the descriptor flags */
+	return dm_gpio_clrset_flags(desc, GPIOD_MASK_DIR, flags);
 }
 
 int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flagsp)
@@ -999,7 +1037,10 @@ 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);
+
+	/* Keep any direction flags provided by the devicetree */
+	ret = dm_gpio_set_dir_flags(desc,
+				    flags | (desc->flags & GPIOD_MASK_DIR));
 	if (ret) {
 		debug("%s: dm_gpio_set_dir failed\n", __func__);
 		goto err;
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c
index c2d7046c0dd..125c237551c 100644
--- a/drivers/gpio/stm32_gpio.c
+++ b/drivers/gpio/stm32_gpio.c
@@ -203,12 +203,13 @@ static int stm32_gpio_set_flags(struct udevice *dev, unsigned int offset,
 		return idx;
 
 	if (flags & GPIOD_IS_OUT) {
-		int value = GPIOD_FLAGS_OUTPUT(flags);
+		bool value = flags & GPIOD_IS_OUT_ACTIVE;
 
 		if (flags & GPIOD_OPEN_DRAIN)
 			stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD);
 		else
 			stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP);
+
 		stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
 		writel(BSRR_BIT(idx, value), &regs->bsrr);
 
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c
index 8ddbc3dc281..711b1a5d8c4 100644
--- a/drivers/pinctrl/pinctrl-stmfx.c
+++ b/drivers/pinctrl/pinctrl-stmfx.c
@@ -169,6 +169,8 @@ static int stmfx_gpio_set_flags(struct udevice *dev, unsigned int offset,
 	int ret = -ENOTSUPP;
 
 	if (flags & GPIOD_IS_OUT) {
+		bool value = flags & GPIOD_IS_OUT_ACTIVE;
+
 		if (flags & GPIOD_OPEN_SOURCE)
 			return -ENOTSUPP;
 		if (flags & GPIOD_OPEN_DRAIN)
@@ -177,8 +179,7 @@ static int stmfx_gpio_set_flags(struct udevice *dev, unsigned int offset,
 			ret = stmfx_conf_set_type(dev, offset, 1);
 		if (ret)
 			return ret;
-		ret = stmfx_gpio_direction_output(dev, offset,
-						  GPIOD_FLAGS_OUTPUT(flags));
+		ret = stmfx_gpio_direction_output(dev, offset, value);
 	} else if (flags & GPIOD_IS_IN) {
 		ret = stmfx_gpio_direction_input(dev, offset);
 		if (ret)
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index f7f10c469c0..af3ce21a7cf 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -128,6 +128,12 @@ struct gpio_desc {
 #define GPIOD_PULL_UP		BIT(7)	/* GPIO has pull-up enabled */
 #define GPIOD_PULL_DOWN		BIT(8)	/* GPIO has pull-down enabled */
 
+/* Flags for updating the above */
+#define GPIOD_MASK_DIR		(GPIOD_IS_OUT | GPIOD_IS_IN | \
+					GPIOD_IS_OUT_ACTIVE)
+#define GPIOD_MASK_DSTYPE	(GPIOD_OPEN_DRAIN | GPIOD_OPEN_SOURCE)
+#define GPIOD_MASK_PULL		(GPIOD_PULL_UP | GPIOD_PULL_DOWN)
+
 	uint offset;		/* GPIO offset within the device */
 	/*
 	 * We could consider adding the GPIO label in here. Possibly we could
@@ -135,12 +141,6 @@ struct gpio_desc {
 	 */
 };
 
-/* helper to compute the value of the gpio output */
-#define GPIOD_FLAGS_OUTPUT_MASK (GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE)
-#define GPIOD_FLAGS_OUTPUT(flags) \
-	(((((flags) & GPIOD_FLAGS_OUTPUT_MASK) == GPIOD_IS_OUT_ACTIVE) || \
-	  (((flags) & GPIOD_FLAGS_OUTPUT_MASK) == GPIOD_ACTIVE_LOW)))
-
 /**
  * dm_gpio_is_valid() - Check if a GPIO is valid
  *
@@ -657,6 +657,25 @@ int dm_gpio_get_value(const struct gpio_desc *desc);
 
 int dm_gpio_set_value(const struct gpio_desc *desc, int value);
 
+/**
+ * dm_gpio_clrset_flags() - Update flags
+ *
+ * This updates the flags as directled. Note that desc->flags is updated by this
+ * function on success. If any changes cannot be made, best efforts are made.
+ *
+ * By use of @clr and @set any of flags can be individually updated, or left
+ * alone
+ *
+ * @desc:	GPIO description containing device, offset and flags,
+ *		previously returned by gpio_request_by_name()
+ * @clr:	Flags to clear (GPIOD_...)
+ * @set:	Flags to set (GPIOD_...)
+ * @return 0 if OK, -EINVAL if the flags had obvious conflicts,
+ * -ERECALLCONFLICT if there was a non-obvious hardware conflict when attempting
+ * to set the flags
+ */
+int dm_gpio_clrset_flags(struct gpio_desc *desc, ulong clr, ulong set);
+
 /**
  * dm_gpio_set_dir_flags() - Set direction using description and added flags
  *
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index dfbb634bf71..be5da953045 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -178,15 +178,15 @@ static int dm_test_gpio_opendrain_opensource(struct unit_test_state *uts)
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
 		    sandbox_gpio_get_flags(gpio_c, 0));
 
-	/* Set it as output high, should become an input */
+	/* Set it as output high */
 	ut_assertok(dm_gpio_set_value(&desc_list[0], 1));
-	ut_assertok(gpio_get_status(gpio_c, 0, buf, sizeof(buf)));
-	ut_asserteq_str("c0: input: 0 [x] a-test.test3-gpios0", buf);
+	ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN | GPIOD_IS_OUT_ACTIVE,
+		    sandbox_gpio_get_flags(gpio_c, 0));
 
-	/* Set it as output low, should become output low */
+	/* Set it as output low */
 	ut_assertok(dm_gpio_set_value(&desc_list[0], 0));
-	ut_assertok(gpio_get_status(gpio_c, 0, buf, sizeof(buf)));
-	ut_asserteq_str("c0: output: 0 [x] a-test.test3-gpios0", buf);
+	ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
+		    sandbox_gpio_get_flags(gpio_c, 0));
 
 	/* GPIO 1 is (GPIO_OUT|GPIO_OPEN_SOURCE) */
 	ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
@@ -197,13 +197,21 @@ static int dm_test_gpio_opendrain_opensource(struct unit_test_state *uts)
 	ut_assertok(gpio_get_status(gpio_c, 1, buf, sizeof(buf)));
 	ut_asserteq_str("c1: output: 1 [x] a-test.test3-gpios1", buf);
 
-	/* Set it as output low, should become an input */
+	/* Set it as output low */
 	ut_assertok(dm_gpio_set_value(&desc_list[1], 0));
+	ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
+		    sandbox_gpio_get_flags(gpio_c, 1));
+
 	ut_assertok(gpio_get_status(gpio_c, 1, buf, sizeof(buf)));
-	ut_asserteq_str("c1: input: 1 [x] a-test.test3-gpios1", buf);
+	ut_asserteq_str("c1: output: 0 [x] a-test.test3-gpios1", buf);
 
-	/* GPIO 6 is (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_DRAIN) */
-	ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
+	/*
+	 * GPIO 6 is (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_DRAIN). Looking at it
+	 * directlt from the driver, we get GPIOD_IS_OUT_ACTIVE also, since it
+	 * is active low
+	 */
+	ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_DRAIN |
+		    GPIOD_IS_OUT_ACTIVE,
 		    sandbox_gpio_get_flags(gpio_c, 6));
 
 	/* Set it as output high, should become output low */
@@ -211,19 +219,21 @@ static int dm_test_gpio_opendrain_opensource(struct unit_test_state *uts)
 	ut_assertok(gpio_get_status(gpio_c, 6, buf, sizeof(buf)));
 	ut_asserteq_str("c6: output: 0 [x] a-test.test3-gpios6", buf);
 
-	/* Set it as output low, should become an input */
+	/* Set it as output low */
 	ut_assertok(dm_gpio_set_value(&desc_list[6], 0));
-	ut_assertok(gpio_get_status(gpio_c, 6, buf, sizeof(buf)));
-	ut_asserteq_str("c6: input: 0 [x] a-test.test3-gpios6", buf);
+	ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_DRAIN |
+		    GPIOD_IS_OUT_ACTIVE,
+		    sandbox_gpio_get_flags(gpio_c, 6));
 
 	/* GPIO 7 is (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_SOURCE) */
-	ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
+	ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_SOURCE |
+		    GPIOD_IS_OUT_ACTIVE,
 		    sandbox_gpio_get_flags(gpio_c, 7));
 
-	/* Set it as output high, should become an input */
+	/* Set it as output high */
 	ut_assertok(dm_gpio_set_value(&desc_list[7], 1));
-	ut_assertok(gpio_get_status(gpio_c, 7, buf, sizeof(buf)));
-	ut_asserteq_str("c7: input: 0 [x] a-test.test3-gpios7", buf);
+	ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
+		    sandbox_gpio_get_flags(gpio_c, 7));
 
 	/* Set it as output low, should become output high */
 	ut_assertok(dm_gpio_set_value(&desc_list[7], 0));
@@ -582,3 +592,91 @@ static int dm_test_gpio_devm(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_gpio_devm, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+static int dm_test_clrset_flags(struct unit_test_state *uts)
+{
+	struct gpio_desc desc;
+	struct udevice *dev;
+	ulong flags;
+
+	ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
+	ut_asserteq_str("a-test", dev->name);
+	ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc, 0));
+
+	ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_OUT));
+	ut_assertok(dm_gpio_get_flags(&desc, &flags));
+	ut_asserteq(GPIOD_IS_OUT, flags);
+	ut_asserteq(GPIOD_IS_OUT, desc.flags);
+	ut_asserteq(0, sandbox_gpio_get_value(desc.dev, desc.offset));
+
+	ut_assertok(dm_gpio_clrset_flags(&desc, 0, GPIOD_IS_OUT_ACTIVE));
+	ut_assertok(dm_gpio_get_flags(&desc, &flags));
+	ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE, flags);
+	ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE, desc.flags);
+	ut_asserteq(1, sandbox_gpio_get_value(desc.dev, desc.offset));
+	ut_asserteq(1, dm_gpio_get_value(&desc));
+
+	ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_IN));
+	ut_assertok(dm_gpio_get_flags(&desc, &flags));
+	ut_asserteq(GPIOD_IS_IN, flags & GPIOD_MASK_DIR);
+	ut_asserteq(GPIOD_IS_IN, desc.flags & GPIOD_MASK_DIR);
+
+	ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_MASK_PULL,
+					 GPIOD_PULL_UP));
+	ut_assertok(dm_gpio_get_flags(&desc, &flags));
+	ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_UP, flags);
+	ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_UP, desc.flags);
+
+	/* Check we cannot set both PULL_UP and PULL_DOWN */
+	ut_asserteq(-EINVAL, dm_gpio_clrset_flags(&desc, 0, GPIOD_PULL_DOWN));
+
+	return 0;
+}
+DM_TEST(dm_test_clrset_flags, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+/* Check that an active-low GPIO works as expected */
+static int dm_test_clrset_flags_invert(struct unit_test_state *uts)
+{
+	struct gpio_desc desc;
+	struct udevice *dev;
+	ulong flags;
+
+	ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
+	ut_asserteq_str("a-test", dev->name);
+	ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc,
+					 GPIOD_IS_OUT | GPIOD_ACTIVE_LOW));
+
+	/*
+	 * From this size we see it as 0 (active low), but the sandbox driver
+	 * sees the pin value high
+	 */
+	ut_asserteq(0, dm_gpio_get_value(&desc));
+	ut_asserteq(1, sandbox_gpio_get_value(desc.dev, desc.offset));
+
+	ut_assertok(dm_gpio_set_value(&desc, 1));
+	ut_asserteq(1, dm_gpio_get_value(&desc));
+	ut_asserteq(0, sandbox_gpio_get_value(desc.dev, desc.offset));
+
+	/* Do the same with dm_gpio_clrset_flags() */
+	ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_IS_OUT_ACTIVE, 0));
+	ut_asserteq(0, dm_gpio_get_value(&desc));
+	ut_asserteq(1, sandbox_gpio_get_value(desc.dev, desc.offset));
+
+	ut_assertok(dm_gpio_clrset_flags(&desc, 0, GPIOD_IS_OUT_ACTIVE));
+	ut_asserteq(1, dm_gpio_get_value(&desc));
+	ut_asserteq(0, sandbox_gpio_get_value(desc.dev, desc.offset));
+
+	ut_assertok(dm_gpio_get_flags(&desc, &flags));
+	ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE,
+		    flags);
+	ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE,
+		    desc.flags);
+
+	ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_IS_OUT_ACTIVE, 0));
+	ut_assertok(dm_gpio_get_flags(&desc, &flags));
+	ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW, flags);
+	ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW, desc.flags);
+
+	return 0;
+}
+DM_TEST(dm_test_clrset_flags_invert, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 11/16] gpio: Replace direction_input() and direction_output()
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (9 preceding siblings ...)
  2021-02-05  4:22 ` [PATCH v4 10/16] dm: gpio: Add a way to update flags Simon Glass
@ 2021-02-05  4:22 ` Simon Glass
  2021-03-04 18:14   ` Tom Rini
  2021-02-05  4:22 ` [PATCH v4 12/16] gpio: Use an 'ops' variable everywhere Simon Glass
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:22 UTC (permalink / raw)
  To: u-boot

The new update_flags() method is more flexible since it allows the
driver to see the full flags all at once. Use that in preference to these
two functions. Add comments to that effect.

Signed-off-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

(no changes since v1)

 drivers/gpio/gpio-uclass.c | 15 ++++++---------
 include/asm-generic/gpio.h | 26 +++++++++++++++++++++++++-
 2 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index daaa1401087..123794994fa 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -512,13 +512,10 @@ int gpio_direction_input(unsigned gpio)
 	int ret;
 
 	ret = gpio_to_device(gpio, &desc);
-	if (ret)
-		return ret;
-	ret = check_reserved(&desc, "dir_input");
 	if (ret)
 		return ret;
 
-	return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
+	return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_IN);
 }
 
 /**
@@ -533,17 +530,17 @@ int gpio_direction_input(unsigned gpio)
 int gpio_direction_output(unsigned gpio, int value)
 {
 	struct gpio_desc desc;
+	ulong flags;
 	int ret;
 
 	ret = gpio_to_device(gpio, &desc);
-	if (ret)
-		return ret;
-	ret = check_reserved(&desc, "dir_output");
 	if (ret)
 		return ret;
 
-	return gpio_get_ops(desc.dev)->direction_output(desc.dev,
-							desc.offset, value);
+	flags = GPIOD_IS_OUT;
+	if (value)
+		flags |= GPIOD_IS_OUT_ACTIVE;
+	return dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, flags);
 }
 
 static int _gpio_get_value(const struct gpio_desc *desc)
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index af3ce21a7cf..457ecb19cd3 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -260,10 +260,32 @@ int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
 struct dm_gpio_ops {
 	int (*request)(struct udevice *dev, unsigned offset, const char *label);
 	int (*rfree)(struct udevice *dev, unsigned int offset);
+
+	/**
+	 * direction_input() - deprecated
+	 *
+	 * Equivalent to set_flags(...GPIOD_IS_IN)
+	 */
 	int (*direction_input)(struct udevice *dev, unsigned offset);
+
+	/**
+	 * direction_output() - deprecated
+	 *
+	 * Equivalent to set_flags(...GPIOD_IS_OUT) with GPIOD_IS_OUT_ACTIVE
+	 * also set if @value
+	 */
 	int (*direction_output)(struct udevice *dev, unsigned offset,
 				int value);
+
 	int (*get_value)(struct udevice *dev, unsigned offset);
+
+	/**
+	 * set_value() - Sets the GPIO value of an output
+	 *
+	 * If the driver provides an @set_flags() method then that is used
+	 * in preference to this, with GPIOD_IS_OUT_ACTIVE set according to
+	 * @value.
+	 */
 	int (*set_value)(struct udevice *dev, unsigned offset, int value);
 	/**
 	 * get_function() Get the GPIO function
@@ -320,7 +342,9 @@ struct dm_gpio_ops {
 	 * uclass, so the driver always sees the value that should be set at the
 	 * pin (1=high, 0=low).
 	 *
-	 * This method is optional.
+	 * This method is required and should be implemented by new drivers. At
+	 * some point, it will supersede direction_input() and
+	 * direction_output(), which wil be removed.
 	 *
 	 * @dev:	GPIO device
 	 * @offset:	GPIO offset within that device
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 12/16] gpio: Use an 'ops' variable everywhere
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (10 preceding siblings ...)
  2021-02-05  4:22 ` [PATCH v4 11/16] gpio: Replace direction_input() and direction_output() Simon Glass
@ 2021-02-05  4:22 ` Simon Glass
  2021-03-04 18:14   ` Tom Rini
  2021-02-05  4:22 ` [PATCH v4 13/16] gpio: x86: Drop the deprecated methods in intel_gpio Simon Glass
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:22 UTC (permalink / raw)
  To: u-boot

Update this driver to use the common method of putting the driver
operations in an 'ops' variable install of calling gpio_get_ops()
repeatedly. Make it const since operations do not change.

Signed-off-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

(no changes since v1)

 drivers/gpio/gpio-uclass.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 123794994fa..11fa17c14b2 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -219,7 +219,7 @@ int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
 static int gpio_find_and_xlate(struct gpio_desc *desc,
 			       struct ofnode_phandle_args *args)
 {
-	struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
+	const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
 
 	if (ops->xlate)
 		return ops->xlate(desc->dev, desc, args);
@@ -352,6 +352,7 @@ int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
 
 int dm_gpio_request(struct gpio_desc *desc, const char *label)
 {
+	const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
 	struct udevice *dev = desc->dev;
 	struct gpio_dev_priv *uc_priv;
 	char *str;
@@ -363,8 +364,8 @@ int dm_gpio_request(struct gpio_desc *desc, const char *label)
 	str = strdup(label);
 	if (!str)
 		return -ENOMEM;
-	if (gpio_get_ops(dev)->request) {
-		ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
+	if (ops->request) {
+		ret = ops->request(dev, desc->offset, label);
 		if (ret) {
 			free(str);
 			return ret;
@@ -441,14 +442,15 @@ int gpio_requestf(unsigned gpio, const char *fmt, ...)
 
 int _dm_gpio_free(struct udevice *dev, uint offset)
 {
+	const struct dm_gpio_ops *ops = gpio_get_ops(dev);
 	struct gpio_dev_priv *uc_priv;
 	int ret;
 
 	uc_priv = dev_get_uclass_priv(dev);
 	if (!uc_priv->name[offset])
 		return -ENXIO;
-	if (gpio_get_ops(dev)->rfree) {
-		ret = gpio_get_ops(dev)->rfree(dev, offset);
+	if (ops->rfree) {
+		ret = ops->rfree(dev, offset);
 		if (ret)
 			return ret;
 	}
@@ -545,9 +547,10 @@ int gpio_direction_output(unsigned gpio, int value)
 
 static int _gpio_get_value(const struct gpio_desc *desc)
 {
+	const struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
 	int value;
 
-	value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
+	value = ops->get_value(desc->dev, desc->offset);
 
 	return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
 }
@@ -643,7 +646,7 @@ static int check_dir_flags(ulong flags)
 static int _dm_gpio_set_flags(struct gpio_desc *desc, ulong flags)
 {
 	struct udevice *dev = desc->dev;
-	struct dm_gpio_ops *ops = gpio_get_ops(dev);
+	const struct dm_gpio_ops *ops = gpio_get_ops(dev);
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	int ret = 0;
 
@@ -710,7 +713,7 @@ int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flagsp)
 {
 	struct udevice *dev = desc->dev;
 	int ret, value;
-	struct dm_gpio_ops *ops = gpio_get_ops(dev);
+	const struct dm_gpio_ops *ops = gpio_get_ops(dev);
 	ulong flags;
 
 	ret = check_reserved(desc, "get_flags");
@@ -808,7 +811,7 @@ static int get_function(struct udevice *dev, int offset, bool skip_unused,
 			const char **namep)
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
-	struct dm_gpio_ops *ops = gpio_get_ops(dev);
+	const struct dm_gpio_ops *ops = gpio_get_ops(dev);
 
 	BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
 	if (!device_active(dev))
@@ -845,7 +848,7 @@ int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
 
 int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
 {
-	struct dm_gpio_ops *ops = gpio_get_ops(dev);
+	const struct dm_gpio_ops *ops = gpio_get_ops(dev);
 	struct gpio_dev_priv *priv;
 	char *str = buf;
 	int func;
@@ -885,7 +888,7 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
 #if CONFIG_IS_ENABLED(ACPIGEN)
 int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio)
 {
-	struct dm_gpio_ops *ops;
+	const struct dm_gpio_ops *ops;
 
 	memset(gpio, '\0', sizeof(*gpio));
 	if (!dm_gpio_is_valid(desc)) {
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 13/16] gpio: x86: Drop the deprecated methods in intel_gpio
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (11 preceding siblings ...)
  2021-02-05  4:22 ` [PATCH v4 12/16] gpio: Use an 'ops' variable everywhere Simon Glass
@ 2021-02-05  4:22 ` Simon Glass
  2021-03-04 18:15   ` Tom Rini
  2021-02-05  4:22 ` [PATCH v4 14/16] gpio: sandbox: Track whether a GPIO is driven Simon Glass
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:22 UTC (permalink / raw)
  To: u-boot

We don't need to implement direction_input() and direction_output()
anymore. Drop them and use update_flags() instead.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

(no changes since v1)

 arch/x86/include/asm/intel_pinctrl_defs.h |  5 ++
 drivers/gpio/intel_gpio.c                 | 72 ++++++++++++-----------
 2 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/arch/x86/include/asm/intel_pinctrl_defs.h b/arch/x86/include/asm/intel_pinctrl_defs.h
index 1ea141f082f..5d83d24bae2 100644
--- a/arch/x86/include/asm/intel_pinctrl_defs.h
+++ b/arch/x86/include/asm/intel_pinctrl_defs.h
@@ -11,6 +11,11 @@
 
 /* This file is included by device trees, so avoid BIT() macros */
 
+#define GPIO_DW_SIZE(x)			(sizeof(u32) * (x))
+#define PAD_CFG_OFFSET(x, dw_num)	((x) + GPIO_DW_SIZE(dw_num))
+#define PAD_CFG0_OFFSET(x)		PAD_CFG_OFFSET(x, 0)
+#define PAD_CFG1_OFFSET(x)		PAD_CFG_OFFSET(x, 1)
+
 #define PAD_CFG0_TX_STATE_BIT		0
 #define PAD_CFG0_TX_STATE		(1 << PAD_CFG0_TX_STATE_BIT)
 #define PAD_CFG0_RX_STATE_BIT		1
diff --git a/drivers/gpio/intel_gpio.c b/drivers/gpio/intel_gpio.c
index eda95485c93..ab46a94dbc1 100644
--- a/drivers/gpio/intel_gpio.c
+++ b/drivers/gpio/intel_gpio.c
@@ -3,6 +3,8 @@
  * Copyright 2019 Google LLC
  */
 
+#define LOG_CATEGORY	UCLASS_GPIO
+
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
@@ -23,38 +25,6 @@
 #include <dm/acpi.h>
 #include <dt-bindings/gpio/x86-gpio.h>
 
-static int intel_gpio_direction_input(struct udevice *dev, uint offset)
-{
-	struct udevice *pinctrl = dev_get_parent(dev);
-	uint config_offset;
-
-	config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
-
-	pcr_clrsetbits32(pinctrl, config_offset,
-			 PAD_CFG0_MODE_MASK | PAD_CFG0_TX_STATE |
-				  PAD_CFG0_RX_DISABLE,
-			 PAD_CFG0_MODE_GPIO | PAD_CFG0_TX_DISABLE);
-
-	return 0;
-}
-
-static int intel_gpio_direction_output(struct udevice *dev, uint offset,
-				       int value)
-{
-	struct udevice *pinctrl = dev_get_parent(dev);
-	uint config_offset;
-
-	config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
-
-	pcr_clrsetbits32(pinctrl, config_offset,
-			 PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE |
-				  PAD_CFG0_TX_DISABLE | PAD_CFG0_TX_STATE,
-			 PAD_CFG0_MODE_GPIO | PAD_CFG0_RX_DISABLE |
-				  (value ? PAD_CFG0_TX_STATE : 0));
-
-	return 0;
-}
-
 static int intel_gpio_get_value(struct udevice *dev, uint offset)
 {
 	struct udevice *pinctrl = dev_get_parent(dev);
@@ -130,6 +100,41 @@ static int intel_gpio_xlate(struct udevice *orig_dev, struct gpio_desc *desc,
 	return 0;
 }
 
+static int intel_gpio_set_flags(struct udevice *dev, unsigned int offset,
+				ulong flags)
+{
+	struct udevice *pinctrl = dev_get_parent(dev);
+	u32 bic0 = 0, bic1 = 0;
+	u32 or0, or1;
+	uint config_offset;
+
+	config_offset = intel_pinctrl_get_config_reg_offset(pinctrl, offset);
+
+	if (flags & GPIOD_IS_OUT) {
+		bic0 |= PAD_CFG0_MODE_MASK | PAD_CFG0_RX_STATE |
+			PAD_CFG0_TX_DISABLE;
+		or0 |= PAD_CFG0_MODE_GPIO | PAD_CFG0_RX_DISABLE;
+	} else if (flags & GPIOD_IS_IN) {
+		bic0 |= PAD_CFG0_MODE_MASK | PAD_CFG0_TX_STATE |
+			PAD_CFG0_RX_DISABLE;
+		or0 |= PAD_CFG0_MODE_GPIO | PAD_CFG0_TX_DISABLE;
+	}
+	if (flags & GPIOD_PULL_UP) {
+		bic1 |= PAD_CFG1_PULL_MASK;
+		or1 |= PAD_CFG1_PULL_UP_20K;
+	} else if (flags & GPIOD_PULL_DOWN) {
+		bic1 |= PAD_CFG1_PULL_MASK;
+		or1 |= PAD_CFG1_PULL_DN_20K;
+	}
+
+	pcr_clrsetbits32(pinctrl, PAD_CFG0_OFFSET(config_offset), bic0, or0);
+	pcr_clrsetbits32(pinctrl, PAD_CFG1_OFFSET(config_offset), bic1, or1);
+	log_debug("%s: flags=%lx, offset=%x, config_offset=%x, %x/%x %x/%x\n",
+		  dev->name, flags, offset, config_offset, bic0, or0, bic1, or1);
+
+	return 0;
+}
+
 #if CONFIG_IS_ENABLED(ACPIGEN)
 static int intel_gpio_get_acpi(const struct gpio_desc *desc,
 			       struct acpi_gpio *gpio)
@@ -177,12 +182,11 @@ static int intel_gpio_of_to_plat(struct udevice *dev)
 }
 
 static const struct dm_gpio_ops gpio_intel_ops = {
-	.direction_input	= intel_gpio_direction_input,
-	.direction_output	= intel_gpio_direction_output,
 	.get_value		= intel_gpio_get_value,
 	.set_value		= intel_gpio_set_value,
 	.get_function		= intel_gpio_get_function,
 	.xlate			= intel_gpio_xlate,
+	.set_flags		= intel_gpio_set_flags,
 #if CONFIG_IS_ENABLED(ACPIGEN)
 	.get_acpi		= intel_gpio_get_acpi,
 #endif
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 14/16] gpio: sandbox: Track whether a GPIO is driven
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (12 preceding siblings ...)
  2021-02-05  4:22 ` [PATCH v4 13/16] gpio: x86: Drop the deprecated methods in intel_gpio Simon Glass
@ 2021-02-05  4:22 ` Simon Glass
  2021-03-04 18:15   ` Tom Rini
  2021-02-05  4:22 ` [PATCH v4 15/16] gpio: Define the log category in the uclass Simon Glass
  2021-02-05  4:22 ` [PATCH v4 16/16] gpio: Add a way to read 3-way strapping pins Simon Glass
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:22 UTC (permalink / raw)
  To: u-boot

Add a new flag to keep track of whether sandbox is driving the pin, or
whether it is expecting an input signal. If it is driving, then the value
of the pin is the value being driven (0 or 1). If not driving, then we
consider the value 0, since we don't currently handle things like pull-ups
yet.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

(no changes since v3)

Changes in v3:
- Use bit 30 for GPIOD_EXT_DRIVEN

 arch/sandbox/include/asm/gpio.h |  3 ++-
 drivers/gpio/sandbox.c          | 21 +++++++++++++++------
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/arch/sandbox/include/asm/gpio.h b/arch/sandbox/include/asm/gpio.h
index 74d7a4cd959..33b83ea4cc3 100644
--- a/arch/sandbox/include/asm/gpio.h
+++ b/arch/sandbox/include/asm/gpio.h
@@ -25,8 +25,9 @@
 
 /* Our own private GPIO flags, which musn't conflict with GPIOD_... */
 #define GPIOD_EXT_HIGH		BIT(31)	/* external source is high (else low) */
+#define GPIOD_EXT_DRIVEN	BIT(30)	/* external source is driven */
 
-#define GPIOD_SANDBOX_MASK	BIT(31)
+#define GPIOD_SANDBOX_MASK	GENMASK(31, 30)
 
 /**
  * Return the simulated value of a GPIO (used only in sandbox test code)
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index d1e561ab5e6..700098446b5 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -76,16 +76,22 @@ static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
 int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
 {
 	struct gpio_state *state = get_gpio_state(dev, offset);
+	bool val;
 
 	if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
 		debug("sandbox_gpio: get_value on output gpio %u\n", offset);
 
-	return state->flags & GPIOD_EXT_HIGH ? true : false;
+	if (state->flags & GPIOD_EXT_DRIVEN)
+		val = state->flags & GPIOD_EXT_HIGH;
+	else
+		val = false;
+
+	return val;
 }
 
 int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
 {
-	set_gpio_flag(dev, offset, GPIOD_EXT_HIGH, value);
+	set_gpio_flag(dev, offset, GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
 
 	return 0;
 }
@@ -142,8 +148,8 @@ static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
 	ret = sandbox_gpio_set_direction(dev, offset, 1);
 	if (ret)
 		return ret;
-	ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE | GPIOD_EXT_HIGH,
-			    value);
+	ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE |
+			    GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
 	if (ret)
 		return ret;
 
@@ -171,8 +177,8 @@ static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
 		return -1;
 	}
 
-	ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE | GPIOD_EXT_HIGH,
-			    value);
+	ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE |
+			    GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
 	if (ret)
 		return ret;
 
@@ -218,10 +224,13 @@ static int sb_gpio_set_flags(struct udevice *dev, unsigned int offset,
 	struct gpio_state *state = get_gpio_state(dev, offset);
 
 	if (flags & GPIOD_IS_OUT) {
+		flags |= GPIOD_EXT_DRIVEN;
 		if (flags & GPIOD_IS_OUT_ACTIVE)
 			flags |= GPIOD_EXT_HIGH;
 		else
 			flags &= ~GPIOD_EXT_HIGH;
+	} else {
+		flags |= state->flags & GPIOD_SANDBOX_MASK;
 	}
 	state->flags = flags;
 
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 15/16] gpio: Define the log category in the uclass
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (13 preceding siblings ...)
  2021-02-05  4:22 ` [PATCH v4 14/16] gpio: sandbox: Track whether a GPIO is driven Simon Glass
@ 2021-02-05  4:22 ` Simon Glass
  2021-03-04 18:15   ` Tom Rini
  2021-02-05  4:22 ` [PATCH v4 16/16] gpio: Add a way to read 3-way strapping pins Simon Glass
  15 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:22 UTC (permalink / raw)
  To: u-boot

This uses log_debug(), etc. but does not define the category. Fix this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

(no changes since v3)

Changes in v3:
- Split out the log-category change to a separate patch

 drivers/gpio/gpio-uclass.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 11fa17c14b2..308e75a1476 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -3,6 +3,8 @@
  * Copyright (c) 2013 Google, Inc
  */
 
+#define LOG_CATEGORY	UCLASS_GPIO
+
 #include <common.h>
 #include <dm.h>
 #include <log.h>
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 16/16] gpio: Add a way to read 3-way strapping pins
  2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
                   ` (14 preceding siblings ...)
  2021-02-05  4:22 ` [PATCH v4 15/16] gpio: Define the log category in the uclass Simon Glass
@ 2021-02-05  4:22 ` Simon Glass
  2021-02-08 18:13   ` Patrick DELAUNAY
  2021-03-04 18:15   ` Tom Rini
  15 siblings, 2 replies; 42+ messages in thread
From: Simon Glass @ 2021-02-05  4:22 UTC (permalink / raw)
  To: u-boot

Using the internal vs. external pull resistors it is possible to get
27 different combinations from 3 strapping pins. Add an implementation
of this.

This involves updating the sandbox GPIO driver to model external and
(weaker) internal pull resistors. The get_value() method now takes account
of what is driving a pin:

   sandbox: GPIOD_EXT_DRIVEN - in which case GPIO_EXT_HIGH provides the
          value
   outside source - in which case GPIO_EXT_PULL_UP/DOWN indicates the
          external state and we work the final state using those flags and
          the internal GPIOD_PULL_UP/DOWN flags

Of course the outside source does not really exist in sandbox. We are just
modelling it for test purpose.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

(no changes since v3)

Changes in v3:
- Use bits 28, 29 for the new flags
- Assert that count parameter is within range
- Redo digit logic to be easier to understand
- Update function comment to explain the meaning of the digits
- Fix 'compare' typo

 arch/sandbox/include/asm/gpio.h |  5 +-
 drivers/gpio/gpio-uclass.c      | 81 +++++++++++++++++++++++++++
 drivers/gpio/sandbox.c          | 13 +++--
 include/asm-generic/gpio.h      | 40 ++++++++++++++
 test/dm/gpio.c                  | 98 +++++++++++++++++++++++++++++++++
 5 files changed, 232 insertions(+), 5 deletions(-)

diff --git a/arch/sandbox/include/asm/gpio.h b/arch/sandbox/include/asm/gpio.h
index 33b83ea4cc3..9e10052667d 100644
--- a/arch/sandbox/include/asm/gpio.h
+++ b/arch/sandbox/include/asm/gpio.h
@@ -26,8 +26,11 @@
 /* Our own private GPIO flags, which musn't conflict with GPIOD_... */
 #define GPIOD_EXT_HIGH		BIT(31)	/* external source is high (else low) */
 #define GPIOD_EXT_DRIVEN	BIT(30)	/* external source is driven */
+#define GPIOD_EXT_PULL_UP	BIT(29)	/* GPIO has external pull-up */
+#define GPIOD_EXT_PULL_DOWN	BIT(28)	/* GPIO has external pull-down */
 
-#define GPIOD_SANDBOX_MASK	GENMASK(31, 30)
+#define GPIOD_EXT_PULL		(BIT(28) | BIT(29))
+#define GPIOD_SANDBOX_MASK	GENMASK(31, 28)
 
 /**
  * Return the simulated value of a GPIO (used only in sandbox test code)
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 308e75a1476..8dc647dc9f8 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -22,6 +22,7 @@
 #include <dm/device_compat.h>
 #include <linux/bug.h>
 #include <linux/ctype.h>
+#include <linux/delay.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -711,6 +712,21 @@ int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
 	return dm_gpio_clrset_flags(desc, GPIOD_MASK_DIR, flags);
 }
 
+int dm_gpios_clrset_flags(struct gpio_desc *desc, int count, ulong clr,
+			  ulong set)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < count; i++) {
+		ret = dm_gpio_clrset_flags(&desc[i], clr, set);
+		if (ret)
+			return log_ret(ret);
+	}
+
+	return 0;
+}
+
 int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flagsp)
 {
 	struct udevice *dev = desc->dev;
@@ -977,6 +993,71 @@ int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
 	return vector;
 }
 
+int dm_gpio_get_values_as_int_base3(struct gpio_desc *desc_list,
+				    int count)
+{
+	static const char tristate[] = "01z";
+	enum {
+		PULLUP,
+		PULLDOWN,
+
+		NUM_OPTIONS,
+	};
+	int vals[NUM_OPTIONS];
+	uint mask;
+	uint vector = 0;
+	int ret, i;
+
+	/*
+	 * Limit to 19 digits which should be plenty. This avoids overflow of a
+	 * 32-bit int
+	 */
+	assert(count < 20);
+
+	for (i = 0; i < NUM_OPTIONS; i++) {
+		uint flags = GPIOD_IS_IN;
+
+		flags |= (i == PULLDOWN) ? GPIOD_PULL_DOWN : GPIOD_PULL_UP;
+		ret = dm_gpios_clrset_flags(desc_list, count, GPIOD_MASK_PULL,
+					    flags);
+		if (ret)
+			return log_msg_ret("pu", ret);
+
+		/* Give the lines time to settle */
+		udelay(10);
+
+		ret = dm_gpio_get_values_as_int(desc_list, count);
+		if (ret < 0)
+			return log_msg_ret("get1", ret);
+		vals[i] = ret;
+	}
+
+	log_debug("values: %x %x, count = %d\n", vals[0], vals[1], count);
+	for (i = count - 1, mask = 1 << i; i >= 0; i--, mask >>= 1) {
+		uint pd = vals[PULLDOWN] & mask ? 1 : 0;
+		uint pu = vals[PULLUP] & mask ? 1 : 0;
+		uint digit;
+
+		/*
+		 * Get value with internal pulldown active. If this is 1 then
+		 * there is a stronger external pullup, which we call 1. If not
+		 * then call it 0.
+		 *
+		 * If the values differ then the pin is floating so we call
+		 * this a 2.
+		 */
+		if (pu == pd)
+			digit = pd;
+		else
+			digit = 2;
+		log_debug("%c ", tristate[digit]);
+		vector = 3 * vector + digit;
+	}
+	log_debug("vector=%d\n", vector);
+
+	return vector;
+}
+
 /**
  * gpio_request_tail: common work for requesting a gpio.
  *
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 700098446b5..d008fdd2224 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -19,7 +19,6 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/gpio/sandbox-gpio.h>
 
-
 struct gpio_state {
 	const char *label;	/* label given by requester */
 	ulong flags;		/* flags (GPIOD_...) */
@@ -81,10 +80,16 @@ int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
 	if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
 		debug("sandbox_gpio: get_value on output gpio %u\n", offset);
 
-	if (state->flags & GPIOD_EXT_DRIVEN)
+	if (state->flags & GPIOD_EXT_DRIVEN) {
 		val = state->flags & GPIOD_EXT_HIGH;
-	else
-		val = false;
+	} else {
+		if (state->flags & GPIOD_EXT_PULL_UP)
+			val = true;
+		else if (state->flags & GPIOD_EXT_PULL_DOWN)
+			val = false;
+		else
+			val = state->flags & GPIOD_PULL_UP;
+	}
 
 	return val;
 }
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 457ecb19cd3..e33cde7abdd 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -497,6 +497,31 @@ int gpio_get_values_as_int(const int *gpio_list);
  */
 int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count);
 
+/**
+ * dm_gpio_get_values_as_int_base3() - Create a base-3 int from a list of GPIOs
+ *
+ * This uses pull-ups/pull-downs to figure out whether a GPIO line is externally
+ * pulled down, pulled up or floating. This allows three different strap values
+ * for each pin:
+ *    0 : external pull-down
+ *    1 : external pull-up
+ *    2 : floating
+ *
+ * With this it is possible to obtain more combinations from the same number of
+ * strapping pins, when compared to dm_gpio_get_values_as_int(). The external
+ * pull resistors should be made stronger that the internal SoC pull resistors,
+ * for this to work.
+ *
+ * With 2 pins, 6 combinations are possible, compared with 4
+ * With 3 pins, 27 are possible, compared with 8
+ *
+ * @desc_list: List of GPIOs to collect
+ * @count: Number of GPIOs
+ * @return resulting integer value, or -ve on error
+ */
+int dm_gpio_get_values_as_int_base3(struct gpio_desc *desc_list,
+				    int count);
+
 /**
  * gpio_claim_vector() - claim a number of GPIOs for input
  *
@@ -714,6 +739,21 @@ int dm_gpio_clrset_flags(struct gpio_desc *desc, ulong clr, ulong set);
  */
 int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags);
 
+/**
+ * dm_gpios_clrset_flags() - Sets flags for a set of GPIOs
+ *
+ * This clears and sets flags individually for each GPIO.
+ *
+ * @desc:	List of GPIOs to update
+ * @count:	Number of GPIOs in the list
+ * @clr:	Flags to clear (GPIOD_...), e.g. GPIOD_MASK_DIR if you are
+ *		changing the direction
+ * @set:	Flags to set (GPIOD_...)
+ * @return 0 if OK, -ve on error
+ */
+int dm_gpios_clrset_flags(struct gpio_desc *desc, int count, ulong clr,
+			  ulong set);
+
 /**
  * dm_gpio_get_flags() - Get flags
  *
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index be5da953045..33ae98701f4 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -680,3 +680,101 @@ static int dm_test_clrset_flags_invert(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_clrset_flags_invert, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+static int set_gpios(struct unit_test_state *uts, struct gpio_desc *desc,
+		     int count, uint value)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		const uint mask = 1 << i;
+
+		ut_assertok(sandbox_gpio_set_value(desc[i].dev, desc[i].offset,
+						   value & mask));
+	}
+
+	return 0;
+}
+
+/* Check that an active-low GPIO works as expected */
+static int dm_test_gpio_get_values_as_int(struct unit_test_state *uts)
+{
+	const int gpio_count = 3;
+	struct gpio_desc desc[gpio_count];
+	struct udevice *dev;
+
+	ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
+	ut_asserteq_str("a-test", dev->name);
+
+	ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc,
+						 gpio_count, GPIOD_IS_IN));
+	ut_assertok(set_gpios(uts, desc, gpio_count, 0));
+	ut_asserteq(0, dm_gpio_get_values_as_int(desc, gpio_count));
+
+	ut_assertok(set_gpios(uts, desc, gpio_count, 5));
+	ut_asserteq(5, dm_gpio_get_values_as_int(desc, gpio_count));
+
+	ut_assertok(set_gpios(uts, desc, gpio_count, 7));
+	ut_asserteq(7, dm_gpio_get_values_as_int(desc, gpio_count));
+
+	return 0;
+}
+DM_TEST(dm_test_gpio_get_values_as_int,
+	UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
+
+/* Check that an active-low GPIO works as expected */
+static int dm_test_gpio_get_values_as_int_base3(struct unit_test_state *uts)
+{
+	const int gpio_count = 3;
+	struct gpio_desc desc[gpio_count];
+	struct udevice *dev;
+
+	ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
+	ut_asserteq_str("a-test", dev->name);
+
+	ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc,
+						 gpio_count, GPIOD_IS_IN));
+
+	/*
+	 * First test the sandbox GPIO driver works as expected. The external
+	 * pull resistor should be stronger than the internal one.
+	 */
+	sandbox_gpio_set_flags(desc[0].dev, desc[0].offset,
+			       GPIOD_IS_IN | GPIOD_EXT_PULL_UP | GPIOD_PULL_UP);
+	ut_asserteq(1, dm_gpio_get_value(desc));
+
+	sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, GPIOD_IS_IN |
+			       GPIOD_EXT_PULL_DOWN | GPIOD_PULL_UP);
+	ut_asserteq(0, dm_gpio_get_value(desc));
+
+	sandbox_gpio_set_flags(desc[0].dev, desc[0].offset,
+			       GPIOD_IS_IN | GPIOD_PULL_UP);
+	ut_asserteq(1, dm_gpio_get_value(desc));
+
+	sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, GPIOD_PULL_DOWN);
+	ut_asserteq(0, dm_gpio_get_value(desc));
+
+	/*
+	 * Set up pins: pull-up (1), pull-down (0) and floating (2). This should
+	 * result in digits 2 0 1, i.e. 2 * 9 + 1 * 3 = 19
+	 */
+	sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, GPIOD_EXT_PULL_UP);
+	sandbox_gpio_set_flags(desc[1].dev, desc[1].offset,
+			       GPIOD_EXT_PULL_DOWN);
+	sandbox_gpio_set_flags(desc[2].dev, desc[2].offset, 0);
+	ut_asserteq(19, dm_gpio_get_values_as_int_base3(desc, gpio_count));
+
+	/*
+	 * Set up pins: floating (2), pull-up (1) and pull-down (0). This should
+	 * result in digits 0 1 2, i.e. 1 * 3 + 2 = 5
+	 */
+	sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, 0);
+	sandbox_gpio_set_flags(desc[1].dev, desc[1].offset, GPIOD_EXT_PULL_UP);
+	sandbox_gpio_set_flags(desc[2].dev, desc[2].offset,
+			       GPIOD_EXT_PULL_DOWN);
+	ut_asserteq(5, dm_gpio_get_values_as_int_base3(desc, gpio_count));
+
+	return 0;
+}
+DM_TEST(dm_test_gpio_get_values_as_int_base3,
+	UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-- 
2.30.0.478.g8a0d178c01-goog

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH v4 10/16] dm: gpio: Add a way to update flags
  2021-02-05  4:22 ` [PATCH v4 10/16] dm: gpio: Add a way to update flags Simon Glass
@ 2021-02-08  9:00   ` Köry Maincent
  2021-02-08 17:33   ` Patrick DELAUNAY
  2021-03-04 18:14   ` Tom Rini
  2 siblings, 0 replies; 42+ messages in thread
From: Köry Maincent @ 2021-02-08  9:00 UTC (permalink / raw)
  To: u-boot

On Thu,  4 Feb 2021 21:22:03 -0700
Simon Glass <sjg@chromium.org> wrote:

> It is convenient to be able to adjust some of the flags for a GPIO while
> leaving others alone. Add a function for this.
> 
> Update dm_gpio_set_dir_flags() to make use of this.
> 
> Also update dm_gpio_set_value() to use this also, since this allows the
> open-drain / open-source features to be implemented directly in the
> driver, rather than using the uclass workaround.
> 
> Update the sandbox tests accordingly. This involves a lot of changes to
> dm_test_gpio_opendrain_opensource() since we no-longer have the direciion
> being reported differently depending on the open drain/open source flags.
> 
> Also update the STM32 drivers to let the uclass handle the active low/high
> logic.
> 
> Drop the GPIOD_FLAGS_OUTPUT() macro which is no-longer used.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
> Changes in v4:
> - Update dm_gpio_set_dir_flags() to clear direction flags first
> 
> Changes in v3:
> - Incorporate GPIOD_FLAGS_OUTPUT() changes from Patrick Delaunay
> 
>  drivers/gpio/gpio-uclass.c      |  75 ++++++++++++++----
>  drivers/gpio/stm32_gpio.c       |   3 +-
>  drivers/pinctrl/pinctrl-stmfx.c |   5 +-
>  include/asm-generic/gpio.h      |  31 ++++++--
>  test/dm/gpio.c                  | 132 ++++++++++++++++++++++++++++----
>  5 files changed, 203 insertions(+), 43 deletions(-)
> 

Tested-by: Kory Maincent <kory.maincent@bootlin.com>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 10/16] dm: gpio: Add a way to update flags
  2021-02-05  4:22 ` [PATCH v4 10/16] dm: gpio: Add a way to update flags Simon Glass
  2021-02-08  9:00   ` Köry Maincent
@ 2021-02-08 17:33   ` Patrick DELAUNAY
  2021-02-09  4:28     ` Simon Glass
  2021-03-04 18:14   ` Tom Rini
  2 siblings, 1 reply; 42+ messages in thread
From: Patrick DELAUNAY @ 2021-02-08 17:33 UTC (permalink / raw)
  To: u-boot

Hi Simon,

2 minor remarks,

On 2/5/21 5:22 AM, Simon Glass wrote:
> It is convenient to be able to adjust some of the flags for a GPIO while
> leaving others alone. Add a function for this.
>
> Update dm_gpio_set_dir_flags() to make use of this.
>
> Also update dm_gpio_set_value() to use this also, since this allows the
> open-drain / open-source features to be implemented directly in the
> driver, rather than using the uclass workaround.
>
> Update the sandbox tests accordingly. This involves a lot of changes to
> dm_test_gpio_opendrain_opensource() since we no-longer have the direciion
> being reported differently depending on the open drain/open source flags.
>
> Also update the STM32 drivers to let the uclass handle the active low/high
> logic.
>
> Drop the GPIOD_FLAGS_OUTPUT() macro which is no-longer used.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v4:
> - Update dm_gpio_set_dir_flags() to clear direction flags first
>
> Changes in v3:
> - Incorporate GPIOD_FLAGS_OUTPUT() changes from Patrick Delaunay
>
>   drivers/gpio/gpio-uclass.c      |  75 ++++++++++++++----
>   drivers/gpio/stm32_gpio.c       |   3 +-
>   drivers/pinctrl/pinctrl-stmfx.c |   5 +-
>   include/asm-generic/gpio.h      |  31 ++++++--
>   test/dm/gpio.c                  | 132 ++++++++++++++++++++++++++++----
>   5 files changed, 203 insertions(+), 43 deletions(-)

(...)

> diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c
> index c2d7046c0dd..125c237551c 100644
> --- a/drivers/gpio/stm32_gpio.c
> +++ b/drivers/gpio/stm32_gpio.c
> @@ -203,12 +203,13 @@ static int stm32_gpio_set_flags(struct udevice *dev, unsigned int offset,
>   		return idx;
>   
>   	if (flags & GPIOD_IS_OUT) {
> -		int value = GPIOD_FLAGS_OUTPUT(flags);
> +		bool value = flags & GPIOD_IS_OUT_ACTIVE;

here the bool variable valeu can be 0 or GPIOD_IS_OUT_ACTIVE = BIT(4), 
so it should have

+ bool value = !!(flags & GPIOD_IS_OUT_ACTIVE);

or

+ int value = flags & GPIOD_IS_OUT_ACTIVE;

PS: not functional impact as

#define BSRR_BIT(gpio_pin, value)??? BIT((gpio_pin) + (value ? 0 : 16))

>   
>   		if (flags & GPIOD_OPEN_DRAIN)
>   			stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD);
>   		else
>   			stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP);
> +
>   		stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
>   		writel(BSRR_BIT(idx, value), &regs->bsrr);
>   
> diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c
> index 8ddbc3dc281..711b1a5d8c4 100644
> --- a/drivers/pinctrl/pinctrl-stmfx.c
> +++ b/drivers/pinctrl/pinctrl-stmfx.c
> @@ -169,6 +169,8 @@ static int stmfx_gpio_set_flags(struct udevice *dev, unsigned int offset,
>   	int ret = -ENOTSUPP;
>   
>   	if (flags & GPIOD_IS_OUT) {
> +		bool value = flags & GPIOD_IS_OUT_ACTIVE;
> +


same here

+		int value = flags & GPIOD_IS_OUT_ACTIVE;
or
+		bool value = !!(flags & GPIOD_IS_OUT_ACTIVE);


But no impact


>   		if (flags & GPIOD_OPEN_SOURCE)
>   			return -ENOTSUPP;
>   		if (flags & GPIOD_OPEN_DRAIN)
> @@ -177,8 +179,7 @@ static int stmfx_gpio_set_flags(struct udevice *dev, unsigned int offset,
>   			ret = stmfx_conf_set_type(dev, offset, 1);
>   		if (ret)
>   			return ret;
> -		ret = stmfx_gpio_direction_output(dev, offset,
> -						  GPIOD_FLAGS_OUTPUT(flags));
> +		ret = stmfx_gpio_direction_output(dev, offset, value);
>   	} else if (flags & GPIOD_IS_IN) {
>   		ret = stmfx_gpio_direction_input(dev, offset);
>   		if (ret)


(...)


With the 2 remarks

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Tested-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Regards,

Patrick

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 16/16] gpio: Add a way to read 3-way strapping pins
  2021-02-05  4:22 ` [PATCH v4 16/16] gpio: Add a way to read 3-way strapping pins Simon Glass
@ 2021-02-08 18:13   ` Patrick DELAUNAY
  2021-02-08 23:41     ` Simon Glass
  2021-03-04 18:15   ` Tom Rini
  1 sibling, 1 reply; 42+ messages in thread
From: Patrick DELAUNAY @ 2021-02-08 18:13 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On 2/5/21 5:22 AM, Simon Glass wrote:
> Using the internal vs. external pull resistors it is possible to get
> 27 different combinations from 3 strapping pins. Add an implementation
> of this.
>
> This involves updating the sandbox GPIO driver to model external and
> (weaker) internal pull resistors. The get_value() method now takes account
> of what is driving a pin:
>
>     sandbox: GPIOD_EXT_DRIVEN - in which case GPIO_EXT_HIGH provides the
>            value
>     outside source - in which case GPIO_EXT_PULL_UP/DOWN indicates the
>            external state and we work the final state using those flags and
>            the internal GPIOD_PULL_UP/DOWN flags
>
> Of course the outside source does not really exist in sandbox. We are just
> modelling it for test purpose.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> (no changes since v3)
>
> Changes in v3:
> - Use bits 28, 29 for the new flags
> - Assert that count parameter is within range
> - Redo digit logic to be easier to understand
> - Update function comment to explain the meaning of the digits
> - Fix 'compare' typo
>
>   arch/sandbox/include/asm/gpio.h |  5 +-
>   drivers/gpio/gpio-uclass.c      | 81 +++++++++++++++++++++++++++
>   drivers/gpio/sandbox.c          | 13 +++--
>   include/asm-generic/gpio.h      | 40 ++++++++++++++
>   test/dm/gpio.c                  | 98 +++++++++++++++++++++++++++++++++
>   5 files changed, 232 insertions(+), 5 deletions(-)
>
(...)
> diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
> index 700098446b5..d008fdd2224 100644
> --- a/drivers/gpio/sandbox.c
> +++ b/drivers/gpio/sandbox.c
> @@ -19,7 +19,6 @@
>   #include <dt-bindings/gpio/gpio.h>
>   #include <dt-bindings/gpio/sandbox-gpio.h>
>   
> -
>   struct gpio_state {
>   	const char *label;	/* label given by requester */
>   	ulong flags;		/* flags (GPIOD_...) */
> @@ -81,10 +80,16 @@ int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
>   	if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
>   		debug("sandbox_gpio: get_value on output gpio %u\n", offset);
>   
> -	if (state->flags & GPIOD_EXT_DRIVEN)
> +	if (state->flags & GPIOD_EXT_DRIVEN) {
>   		val = state->flags & GPIOD_EXT_HIGH;

bool here, not int

+ val = !!(state->flags & GPIOD_EXT_HIGH);


> -	else
> -		val = false;
> +	} else {
> +		if (state->flags & GPIOD_EXT_PULL_UP)
> +			val = true;
> +		else if (state->flags & GPIOD_EXT_PULL_DOWN)
> +			val = false;
> +		else
> +			val = state->flags & GPIOD_PULL_UP;

bool also

+ val = !!(state->flags & GPIOD_PULL_UP );


> +	}
>   
>   	return val;
>   }


(...)

Just to be sure that the sandbox gpio value is 0 or 1

with the current code, sandbox_gpio_get_value can return GPIOD_EXT_HIGH 
or GPIOD_PULL_UP, and it is strange (even if result in int).


with these 2 changes, you can add my? Reviewed-by


Regards

Patrick

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 16/16] gpio: Add a way to read 3-way strapping pins
  2021-02-08 18:13   ` Patrick DELAUNAY
@ 2021-02-08 23:41     ` Simon Glass
  0 siblings, 0 replies; 42+ messages in thread
From: Simon Glass @ 2021-02-08 23:41 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

On Mon, 8 Feb 2021 at 11:13, Patrick DELAUNAY
<patrick.delaunay@foss.st.com> wrote:
>
> Hi Simon,
>
> On 2/5/21 5:22 AM, Simon Glass wrote:
> > Using the internal vs. external pull resistors it is possible to get
> > 27 different combinations from 3 strapping pins. Add an implementation
> > of this.
> >
> > This involves updating the sandbox GPIO driver to model external and
> > (weaker) internal pull resistors. The get_value() method now takes account
> > of what is driving a pin:
> >
> >     sandbox: GPIOD_EXT_DRIVEN - in which case GPIO_EXT_HIGH provides the
> >            value
> >     outside source - in which case GPIO_EXT_PULL_UP/DOWN indicates the
> >            external state and we work the final state using those flags and
> >            the internal GPIOD_PULL_UP/DOWN flags
> >
> > Of course the outside source does not really exist in sandbox. We are just
> > modelling it for test purpose.
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> >
> > (no changes since v3)
> >
> > Changes in v3:
> > - Use bits 28, 29 for the new flags
> > - Assert that count parameter is within range
> > - Redo digit logic to be easier to understand
> > - Update function comment to explain the meaning of the digits
> > - Fix 'compare' typo
> >
> >   arch/sandbox/include/asm/gpio.h |  5 +-
> >   drivers/gpio/gpio-uclass.c      | 81 +++++++++++++++++++++++++++
> >   drivers/gpio/sandbox.c          | 13 +++--
> >   include/asm-generic/gpio.h      | 40 ++++++++++++++
> >   test/dm/gpio.c                  | 98 +++++++++++++++++++++++++++++++++
> >   5 files changed, 232 insertions(+), 5 deletions(-)
> >
> (...)
> > diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
> > index 700098446b5..d008fdd2224 100644
> > --- a/drivers/gpio/sandbox.c
> > +++ b/drivers/gpio/sandbox.c
> > @@ -19,7 +19,6 @@
> >   #include <dt-bindings/gpio/gpio.h>
> >   #include <dt-bindings/gpio/sandbox-gpio.h>
> >
> > -
> >   struct gpio_state {
> >       const char *label;      /* label given by requester */
> >       ulong flags;            /* flags (GPIOD_...) */
> > @@ -81,10 +80,16 @@ int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
> >       if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
> >               debug("sandbox_gpio: get_value on output gpio %u\n", offset);
> >
> > -     if (state->flags & GPIOD_EXT_DRIVEN)
> > +     if (state->flags & GPIOD_EXT_DRIVEN) {
> >               val = state->flags & GPIOD_EXT_HIGH;
>
> bool here, not int
>
> + val = !!(state->flags & GPIOD_EXT_HIGH);
>
>
> > -     else
> > -             val = false;
> > +     } else {
> > +             if (state->flags & GPIOD_EXT_PULL_UP)
> > +                     val = true;
> > +             else if (state->flags & GPIOD_EXT_PULL_DOWN)
> > +                     val = false;
> > +             else
> > +                     val = state->flags & GPIOD_PULL_UP;
>
> bool also
>
> + val = !!(state->flags & GPIOD_PULL_UP );
>
>
> > +     }
> >
> >       return val;
> >   }
>
>
> (...)
>
> Just to be sure that the sandbox gpio value is 0 or 1
>
> with the current code, sandbox_gpio_get_value can return GPIOD_EXT_HIGH
> or GPIOD_PULL_UP, and it is strange (even if result in int).

I think that is a hack to work around not having a 'bool' type, but we
do have one in U-Boot, so I feel it is better to use it, instead using
!!

See the 'bool val;' in that function.

>
>
> with these 2 changes, you can add my  Reviewed-by

Regards,
Simon

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 10/16] dm: gpio: Add a way to update flags
  2021-02-08 17:33   ` Patrick DELAUNAY
@ 2021-02-09  4:28     ` Simon Glass
  2021-02-10  8:38       ` Patrick DELAUNAY
  0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-02-09  4:28 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

On Mon, 8 Feb 2021 at 10:33, Patrick DELAUNAY
<patrick.delaunay@foss.st.com> wrote:
>
> Hi Simon,
>
> 2 minor remarks,
>
> On 2/5/21 5:22 AM, Simon Glass wrote:
> > It is convenient to be able to adjust some of the flags for a GPIO while
> > leaving others alone. Add a function for this.
> >
> > Update dm_gpio_set_dir_flags() to make use of this.
> >
> > Also update dm_gpio_set_value() to use this also, since this allows the
> > open-drain / open-source features to be implemented directly in the
> > driver, rather than using the uclass workaround.
> >
> > Update the sandbox tests accordingly. This involves a lot of changes to
> > dm_test_gpio_opendrain_opensource() since we no-longer have the direciion
> > being reported differently depending on the open drain/open source flags.
> >
> > Also update the STM32 drivers to let the uclass handle the active low/high
> > logic.
> >
> > Drop the GPIOD_FLAGS_OUTPUT() macro which is no-longer used.
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> >
> > Changes in v4:
> > - Update dm_gpio_set_dir_flags() to clear direction flags first
> >
> > Changes in v3:
> > - Incorporate GPIOD_FLAGS_OUTPUT() changes from Patrick Delaunay
> >
> >   drivers/gpio/gpio-uclass.c      |  75 ++++++++++++++----
> >   drivers/gpio/stm32_gpio.c       |   3 +-
> >   drivers/pinctrl/pinctrl-stmfx.c |   5 +-
> >   include/asm-generic/gpio.h      |  31 ++++++--
> >   test/dm/gpio.c                  | 132 ++++++++++++++++++++++++++++----
> >   5 files changed, 203 insertions(+), 43 deletions(-)
>
> (...)
>
> > diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c
> > index c2d7046c0dd..125c237551c 100644
> > --- a/drivers/gpio/stm32_gpio.c
> > +++ b/drivers/gpio/stm32_gpio.c
> > @@ -203,12 +203,13 @@ static int stm32_gpio_set_flags(struct udevice *dev, unsigned int offset,
> >               return idx;
> >
> >       if (flags & GPIOD_IS_OUT) {
> > -             int value = GPIOD_FLAGS_OUTPUT(flags);
> > +             bool value = flags & GPIOD_IS_OUT_ACTIVE;
>
> here the bool variable valeu can be 0 or GPIOD_IS_OUT_ACTIVE = BIT(4),
> so it should have
>
> + bool value = !!(flags & GPIOD_IS_OUT_ACTIVE);
>
> or
>
> + int value = flags & GPIOD_IS_OUT_ACTIVE;
>
> PS: not functional impact as
>
> #define BSRR_BIT(gpio_pin, value)    BIT((gpio_pin) + (value ? 0 : 16))
>
> >
> >               if (flags & GPIOD_OPEN_DRAIN)
> >                       stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD);
> >               else
> >                       stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP);
> > +
> >               stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
> >               writel(BSRR_BIT(idx, value), &regs->bsrr);
> >
> > diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c
> > index 8ddbc3dc281..711b1a5d8c4 100644
> > --- a/drivers/pinctrl/pinctrl-stmfx.c
> > +++ b/drivers/pinctrl/pinctrl-stmfx.c
> > @@ -169,6 +169,8 @@ static int stmfx_gpio_set_flags(struct udevice *dev, unsigned int offset,
> >       int ret = -ENOTSUPP;
> >
> >       if (flags & GPIOD_IS_OUT) {
> > +             bool value = flags & GPIOD_IS_OUT_ACTIVE;
> > +
>
>
> same here
>
> +               int value = flags & GPIOD_IS_OUT_ACTIVE;
> or
> +               bool value = !!(flags & GPIOD_IS_OUT_ACTIVE);

The bool type should do this automatically. I tested this and it seems
to do the right thing.


>
>
> But no impact
>
>
> >               if (flags & GPIOD_OPEN_SOURCE)
> >                       return -ENOTSUPP;
> >               if (flags & GPIOD_OPEN_DRAIN)
> > @@ -177,8 +179,7 @@ static int stmfx_gpio_set_flags(struct udevice *dev, unsigned int offset,
> >                       ret = stmfx_conf_set_type(dev, offset, 1);
> >               if (ret)
> >                       return ret;
> > -             ret = stmfx_gpio_direction_output(dev, offset,
> > -                                               GPIOD_FLAGS_OUTPUT(flags));
> > +             ret = stmfx_gpio_direction_output(dev, offset, value);
> >       } else if (flags & GPIOD_IS_IN) {
> >               ret = stmfx_gpio_direction_input(dev, offset);
> >               if (ret)
>
>
> (...)
>
>
> With the 2 remarks
>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Tested-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
>

Regards,
SImon

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 10/16] dm: gpio: Add a way to update flags
  2021-02-09  4:28     ` Simon Glass
@ 2021-02-10  8:38       ` Patrick DELAUNAY
  2021-02-13  4:17         ` Simon Glass
  0 siblings, 1 reply; 42+ messages in thread
From: Patrick DELAUNAY @ 2021-02-10  8:38 UTC (permalink / raw)
  To: u-boot


On 2/9/21 5:28 AM, Simon Glass wrote:
> Hi Patrick,
>
> On Mon, 8 Feb 2021 at 10:33, Patrick DELAUNAY
> <patrick.delaunay@foss.st.com> wrote:
>> Hi Simon,
>>
>> 2 minor remarks,
>>
>> On 2/5/21 5:22 AM, Simon Glass wrote:
>>> It is convenient to be able to adjust some of the flags for a GPIO while
>>> leaving others alone. Add a function for this.
>>>
>>> Update dm_gpio_set_dir_flags() to make use of this.
>>>
>>> Also update dm_gpio_set_value() to use this also, since this allows the
>>> open-drain / open-source features to be implemented directly in the
>>> driver, rather than using the uclass workaround.
>>>
>>> Update the sandbox tests accordingly. This involves a lot of changes to
>>> dm_test_gpio_opendrain_opensource() since we no-longer have the direciion
>>> being reported differently depending on the open drain/open source flags.
>>>
>>> Also update the STM32 drivers to let the uclass handle the active low/high
>>> logic.
>>>
>>> Drop the GPIOD_FLAGS_OUTPUT() macro which is no-longer used.
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>> ---
>>>
>>> Changes in v4:
>>> - Update dm_gpio_set_dir_flags() to clear direction flags first
>>>
>>> Changes in v3:
>>> - Incorporate GPIOD_FLAGS_OUTPUT() changes from Patrick Delaunay
>>>
>>>    drivers/gpio/gpio-uclass.c      |  75 ++++++++++++++----
>>>    drivers/gpio/stm32_gpio.c       |   3 +-
>>>    drivers/pinctrl/pinctrl-stmfx.c |   5 +-
>>>    include/asm-generic/gpio.h      |  31 ++++++--
>>>    test/dm/gpio.c                  | 132 ++++++++++++++++++++++++++++----
>>>    5 files changed, 203 insertions(+), 43 deletions(-)
>> (...)
>>
>>> diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c
>>> index c2d7046c0dd..125c237551c 100644
>>> --- a/drivers/gpio/stm32_gpio.c
>>> +++ b/drivers/gpio/stm32_gpio.c
>>> @@ -203,12 +203,13 @@ static int stm32_gpio_set_flags(struct udevice *dev, unsigned int offset,
>>>                return idx;
>>>
>>>        if (flags & GPIOD_IS_OUT) {
>>> -             int value = GPIOD_FLAGS_OUTPUT(flags);
>>> +             bool value = flags & GPIOD_IS_OUT_ACTIVE;
>> here the bool variable valeu can be 0 or GPIOD_IS_OUT_ACTIVE = BIT(4),
>> so it should have
>>
>> + bool value = !!(flags & GPIOD_IS_OUT_ACTIVE);
>>
>> or
>>
>> + int value = flags & GPIOD_IS_OUT_ACTIVE;
>>
>> PS: not functional impact as
>>
>> #define BSRR_BIT(gpio_pin, value)    BIT((gpio_pin) + (value ? 0 : 16))
>>
>>>                if (flags & GPIOD_OPEN_DRAIN)
>>>                        stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD);
>>>                else
>>>                        stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP);
>>> +
>>>                stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
>>>                writel(BSRR_BIT(idx, value), &regs->bsrr);
>>>
>>> diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c
>>> index 8ddbc3dc281..711b1a5d8c4 100644
>>> --- a/drivers/pinctrl/pinctrl-stmfx.c
>>> +++ b/drivers/pinctrl/pinctrl-stmfx.c
>>> @@ -169,6 +169,8 @@ static int stmfx_gpio_set_flags(struct udevice *dev, unsigned int offset,
>>>        int ret = -ENOTSUPP;
>>>
>>>        if (flags & GPIOD_IS_OUT) {
>>> +             bool value = flags & GPIOD_IS_OUT_ACTIVE;
>>> +
>>
>> same here
>>
>> +               int value = flags & GPIOD_IS_OUT_ACTIVE;
>> or
>> +               bool value = !!(flags & GPIOD_IS_OUT_ACTIVE);
> The bool type should do this automatically. I tested this and it seems
> to do the right thing.
>
I confirmed that it is working, forget my remarks.

for information: I tested it in stm32MP157C-DK2 board (with gcc 9.2)....


After check, it is my old habit / coding rule, when the bool type

don't exist in C (it was a typedef to int)

but, since C++ introducing a proper bool type,

the cast to 'bool' is enough with current compilers .

>
> Regards,
> SImon


Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Tested-by: Patrick Delaunay <patrick.delaunay@foss.st.com>


Regards

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 10/16] dm: gpio: Add a way to update flags
  2021-02-10  8:38       ` Patrick DELAUNAY
@ 2021-02-13  4:17         ` Simon Glass
  0 siblings, 0 replies; 42+ messages in thread
From: Simon Glass @ 2021-02-13  4:17 UTC (permalink / raw)
  To: u-boot

Hi Patrick,

On Wed, 10 Feb 2021 at 01:38, Patrick DELAUNAY
<patrick.delaunay@foss.st.com> wrote:
>
>
> On 2/9/21 5:28 AM, Simon Glass wrote:
> > Hi Patrick,
> >
> > On Mon, 8 Feb 2021 at 10:33, Patrick DELAUNAY
> > <patrick.delaunay@foss.st.com> wrote:
> >> Hi Simon,
> >>
> >> 2 minor remarks,
> >>
> >> On 2/5/21 5:22 AM, Simon Glass wrote:
> >>> It is convenient to be able to adjust some of the flags for a GPIO while
> >>> leaving others alone. Add a function for this.
> >>>
> >>> Update dm_gpio_set_dir_flags() to make use of this.
> >>>
> >>> Also update dm_gpio_set_value() to use this also, since this allows the
> >>> open-drain / open-source features to be implemented directly in the
> >>> driver, rather than using the uclass workaround.
> >>>
> >>> Update the sandbox tests accordingly. This involves a lot of changes to
> >>> dm_test_gpio_opendrain_opensource() since we no-longer have the direciion
> >>> being reported differently depending on the open drain/open source flags.
> >>>
> >>> Also update the STM32 drivers to let the uclass handle the active low/high
> >>> logic.
> >>>
> >>> Drop the GPIOD_FLAGS_OUTPUT() macro which is no-longer used.
> >>>
> >>> Signed-off-by: Simon Glass <sjg@chromium.org>
> >>> ---
> >>>
> >>> Changes in v4:
> >>> - Update dm_gpio_set_dir_flags() to clear direction flags first
> >>>
> >>> Changes in v3:
> >>> - Incorporate GPIOD_FLAGS_OUTPUT() changes from Patrick Delaunay
> >>>
> >>>    drivers/gpio/gpio-uclass.c      |  75 ++++++++++++++----
> >>>    drivers/gpio/stm32_gpio.c       |   3 +-
> >>>    drivers/pinctrl/pinctrl-stmfx.c |   5 +-
> >>>    include/asm-generic/gpio.h      |  31 ++++++--
> >>>    test/dm/gpio.c                  | 132 ++++++++++++++++++++++++++++----
> >>>    5 files changed, 203 insertions(+), 43 deletions(-)
> >> (...)
> >>
> >>> diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c
> >>> index c2d7046c0dd..125c237551c 100644
> >>> --- a/drivers/gpio/stm32_gpio.c
> >>> +++ b/drivers/gpio/stm32_gpio.c
> >>> @@ -203,12 +203,13 @@ static int stm32_gpio_set_flags(struct udevice *dev, unsigned int offset,
> >>>                return idx;
> >>>
> >>>        if (flags & GPIOD_IS_OUT) {
> >>> -             int value = GPIOD_FLAGS_OUTPUT(flags);
> >>> +             bool value = flags & GPIOD_IS_OUT_ACTIVE;
> >> here the bool variable valeu can be 0 or GPIOD_IS_OUT_ACTIVE = BIT(4),
> >> so it should have
> >>
> >> + bool value = !!(flags & GPIOD_IS_OUT_ACTIVE);
> >>
> >> or
> >>
> >> + int value = flags & GPIOD_IS_OUT_ACTIVE;
> >>
> >> PS: not functional impact as
> >>
> >> #define BSRR_BIT(gpio_pin, value)    BIT((gpio_pin) + (value ? 0 : 16))
> >>
> >>>                if (flags & GPIOD_OPEN_DRAIN)
> >>>                        stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD);
> >>>                else
> >>>                        stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP);
> >>> +
> >>>                stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
> >>>                writel(BSRR_BIT(idx, value), &regs->bsrr);
> >>>
> >>> diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c
> >>> index 8ddbc3dc281..711b1a5d8c4 100644
> >>> --- a/drivers/pinctrl/pinctrl-stmfx.c
> >>> +++ b/drivers/pinctrl/pinctrl-stmfx.c
> >>> @@ -169,6 +169,8 @@ static int stmfx_gpio_set_flags(struct udevice *dev, unsigned int offset,
> >>>        int ret = -ENOTSUPP;
> >>>
> >>>        if (flags & GPIOD_IS_OUT) {
> >>> +             bool value = flags & GPIOD_IS_OUT_ACTIVE;
> >>> +
> >>
> >> same here
> >>
> >> +               int value = flags & GPIOD_IS_OUT_ACTIVE;
> >> or
> >> +               bool value = !!(flags & GPIOD_IS_OUT_ACTIVE);
> > The bool type should do this automatically. I tested this and it seems
> > to do the right thing.
> >
> I confirmed that it is working, forget my remarks.
>
> for information: I tested it in stm32MP157C-DK2 board (with gcc 9.2)....
>
>
> After check, it is my old habit / coding rule, when the bool type
>
> don't exist in C (it was a typedef to int)
>
> but, since C++ introducing a proper bool type,
>
> the cast to 'bool' is enough with current compilers .

Yes I am still getting used to it myself!

>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
>
> Tested-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Regards,
Simon

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 05/16] gpio: Drop dm_gpio_set_dir()
  2021-02-05  4:21 ` [PATCH v4 05/16] gpio: Drop dm_gpio_set_dir() Simon Glass
@ 2021-03-03 20:39   ` Tom Rini
  2021-03-04 14:22     ` Simon Glass
  0 siblings, 1 reply; 42+ messages in thread
From: Tom Rini @ 2021-03-03 20:39 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:21:58PM -0700, Simon Glass wrote:

> This function is not used. Drop it.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> 
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

I'm dropping this patch as it seems to be an explicit break of:
commit 6befb51f349459c96ed64412070feda7472cf152
Author: Harm Berntsen <harm.berntsen@nedap.com>
Date:   Sun Nov 29 09:47:15 2020 +0000

    i2c: i2c-gpio: Fix GPIO output
    
    The dm_gpio_set_dir_flags function cannot be used to update the
    configuration of a GPIO pin because it does a bitwise OR with the
    existing flags. Looks like commit 788ea834124b ("gpio: add function
    _dm_gpio_set_dir_flags") has introduced this behaviour and the i2c-gpio
    driver has been broken since.
    
    Signed-off-by: Harm Berntsen <harm.berntsen@nedap.com>
    CC: Heiko Schocher <hs@denx.de>
    CC: Patrick Delaunay <patrick.delaunay@st.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210303/c7e72a34/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 05/16] gpio: Drop dm_gpio_set_dir()
  2021-03-03 20:39   ` Tom Rini
@ 2021-03-04 14:22     ` Simon Glass
  2021-03-04 15:09       ` Tom Rini
  0 siblings, 1 reply; 42+ messages in thread
From: Simon Glass @ 2021-03-04 14:22 UTC (permalink / raw)
  To: u-boot

Hi Tom,

On Wed, 3 Mar 2021 at 15:39, Tom Rini <trini@konsulko.com> wrote:
>
> On Thu, Feb 04, 2021 at 09:21:58PM -0700, Simon Glass wrote:
>
> > This function is not used. Drop it.
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> >
> > Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
>
> I'm dropping this patch as it seems to be an explicit break of:
> commit 6befb51f349459c96ed64412070feda7472cf152
> Author: Harm Berntsen <harm.berntsen@nedap.com>
> Date:   Sun Nov 29 09:47:15 2020 +0000
>
>     i2c: i2c-gpio: Fix GPIO output
>
>     The dm_gpio_set_dir_flags function cannot be used to update the
>     configuration of a GPIO pin because it does a bitwise OR with the
>     existing flags. Looks like commit 788ea834124b ("gpio: add function
>     _dm_gpio_set_dir_flags") has introduced this behaviour and the i2c-gpio
>     driver has been broken since.
>
>     Signed-off-by: Harm Berntsen <harm.berntsen@nedap.com>
>     CC: Heiko Schocher <hs@denx.de>
>     CC: Patrick Delaunay <patrick.delaunay@st.com>

Yes I noticed that but only recently, somehow. I have a patch to adjust it.

Does this mean you are planning to apply the rest of the series? If so
I'll see how things land and send a patch after that.

Regards,
Simon

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 05/16] gpio: Drop dm_gpio_set_dir()
  2021-03-04 14:22     ` Simon Glass
@ 2021-03-04 15:09       ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 15:09 UTC (permalink / raw)
  To: u-boot

On Thu, Mar 04, 2021 at 09:22:35AM -0500, Simon Glass wrote:
> Hi Tom,
> 
> On Wed, 3 Mar 2021 at 15:39, Tom Rini <trini@konsulko.com> wrote:
> >
> > On Thu, Feb 04, 2021 at 09:21:58PM -0700, Simon Glass wrote:
> >
> > > This function is not used. Drop it.
> > >
> > > Signed-off-by: Simon Glass <sjg@chromium.org>
> > >
> > > Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> >
> > I'm dropping this patch as it seems to be an explicit break of:
> > commit 6befb51f349459c96ed64412070feda7472cf152
> > Author: Harm Berntsen <harm.berntsen@nedap.com>
> > Date:   Sun Nov 29 09:47:15 2020 +0000
> >
> >     i2c: i2c-gpio: Fix GPIO output
> >
> >     The dm_gpio_set_dir_flags function cannot be used to update the
> >     configuration of a GPIO pin because it does a bitwise OR with the
> >     existing flags. Looks like commit 788ea834124b ("gpio: add function
> >     _dm_gpio_set_dir_flags") has introduced this behaviour and the i2c-gpio
> >     driver has been broken since.
> >
> >     Signed-off-by: Harm Berntsen <harm.berntsen@nedap.com>
> >     CC: Heiko Schocher <hs@denx.de>
> >     CC: Patrick Delaunay <patrick.delaunay@st.com>
> 
> Yes I noticed that but only recently, somehow. I have a patch to adjust it.
> 
> Does this mean you are planning to apply the rest of the series? If so
> I'll see how things land and send a patch after that.

Yes, I have the rest of the series about to go in to -next.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/9d3e8396/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 01/16] gpio: Disable functions not used with of-platdata
  2021-02-05  4:21 ` [PATCH v4 01/16] gpio: Disable functions not used with of-platdata Simon Glass
@ 2021-03-04 18:13   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:13 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:21:54PM -0700, Simon Glass wrote:

> These functions use devicetree and cannot work with of-platdata, which has
> no runtime devicetree.
> 
> If they are used, the current linker error is confusing, since it talks
> about missing functions in the bowels of driver model.
> 
> Avoid compiling these functions at all with of-platdata, so that a
> straightforward link error points to the problem.
> 
> Series-changes; 3
> - Fix 'wprl' typo
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> 
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/911e0431/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 02/16] dm: gpio: Rename set_dir_flags() method to update_flags()
  2021-02-05  4:21 ` [PATCH v4 02/16] dm: gpio: Rename set_dir_flags() method to update_flags() Simon Glass
@ 2021-03-04 18:14   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:14 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:21:55PM -0700, Simon Glass wrote:

> The current method is a misnomer since it is also used (e.g. by stm32) to
> update pull settings and open source/open drain.
> 
> Rename it and expand the documentation to cover a few more details.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
> 
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/64df87f5/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 03/16] dm: gpio: Rename get_dir_flags() method to get_flags()
  2021-02-05  4:21 ` [PATCH v4 03/16] dm: gpio: Rename get_dir_flags() method to get_flags() Simon Glass
@ 2021-03-04 18:14   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:14 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:21:56PM -0700, Simon Glass wrote:

> It is more useful to be able to read all the flags, not just the direction
> ones. In fact this is what the STM32 driver does. Update the method name
> to reflect this.
> 
> Tweak the docs a little and use 'flagsp' as the return argument, as is
> common in driver model, to indicate it returns a value.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> 
> Reviewed-by: Pratyush Yadav <p.yadav@ti.com>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/68d25c80/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 04/16] gpio: Rename dm_gpio_get_dir_flags() to dm_gpio_get_flags()
  2021-02-05  4:21 ` [PATCH v4 04/16] gpio: Rename dm_gpio_get_dir_flags() to dm_gpio_get_flags() Simon Glass
@ 2021-03-04 18:14   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:14 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:21:57PM -0700, Simon Glass wrote:

> This function can be used to get any flags, not just direction flags.
> Rename it to avoid confusion.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Reviewed-by: Pratyush Yadav <p.yadav@ti.com>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/13d7f44a/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 06/16] gpio: sandbox: Rename GPIO dir_flags to flags
  2021-02-05  4:21 ` [PATCH v4 06/16] gpio: sandbox: Rename GPIO dir_flags to flags Simon Glass
@ 2021-03-04 18:14   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:14 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:21:59PM -0700, Simon Glass wrote:

> Adjust the terminology in this driver to reflect that fact that all flags
> are handled, not just direction flags.
> 
> Create a new access function to get the full GPIO state, not just the
> direction flags. Drop the static invalid_dir_flags since we can rely on a
> segfault if something is wrong.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/b0452d93/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 07/16] gpio: sandbox: Use a separate flag for the value
  2021-02-05  4:22 ` [PATCH v4 07/16] gpio: sandbox: Use a separate flag for the value Simon Glass
@ 2021-03-04 18:14   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:14 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:22:00PM -0700, Simon Glass wrote:

> At present with the sandbox GPIO driver it is not possible to change the
> value of GPIOD_IS_OUT_ACTIVE unless the GPIO is an output. This makes it
> hard to test changing the flags since we need to be aware of the internal
> workings of the driver.
> 
> The feature is designed to aid testing.
> 
> Split this feature out into a separate sandbox-specific flag, so that the
> flags can change unimpeded. This will make it easier to allow updating the
> flags in a future patch.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/955afc0a/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 08/16] gpio: sandbox: Fully separate pin value from output value
  2021-02-05  4:22 ` [PATCH v4 08/16] gpio: sandbox: Fully separate pin value from output value Simon Glass
@ 2021-03-04 18:14   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:14 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:22:01PM -0700, Simon Glass wrote:

> At present we have the concept of a pin's external value. This is what
> is used when getting the value of a pin. But we still set the
> GPIOD_IS_OUT_ACTIVE flag when changing the value. This is not actually
> correct, since if the pin changes from output to input, the external
> value need not change. Adjust the logic for this difference.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> 
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/8852eab1/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 09/16] gpio: sandbox: Make sandbox_gpio_set_flags() set all flags
  2021-02-05  4:22 ` [PATCH v4 09/16] gpio: sandbox: Make sandbox_gpio_set_flags() set all flags Simon Glass
@ 2021-03-04 18:14   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:14 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:22:02PM -0700, Simon Glass wrote:

> Allow this function to see all flags, including the internal sandbox ones.
> This allows the tests to fully control the behaviour of the driver.
> 
> To make this work, move the setting of GPIOD_EXT_HIGH -to where the flags
> are updated via driver model, rather than the sandbox 'back door'.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> 
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/79848a6c/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 10/16] dm: gpio: Add a way to update flags
  2021-02-05  4:22 ` [PATCH v4 10/16] dm: gpio: Add a way to update flags Simon Glass
  2021-02-08  9:00   ` Köry Maincent
  2021-02-08 17:33   ` Patrick DELAUNAY
@ 2021-03-04 18:14   ` Tom Rini
  2 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:14 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:22:03PM -0700, Simon Glass wrote:

> It is convenient to be able to adjust some of the flags for a GPIO while
> leaving others alone. Add a function for this.
> 
> Update dm_gpio_set_dir_flags() to make use of this.
> 
> Also update dm_gpio_set_value() to use this also, since this allows the
> open-drain / open-source features to be implemented directly in the
> driver, rather than using the uclass workaround.
> 
> Update the sandbox tests accordingly. This involves a lot of changes to
> dm_test_gpio_opendrain_opensource() since we no-longer have the direciion
> being reported differently depending on the open drain/open source flags.
> 
> Also update the STM32 drivers to let the uclass handle the active low/high
> logic.
> 
> Drop the GPIOD_FLAGS_OUTPUT() macro which is no-longer used.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Tested-by: Kory Maincent <kory.maincent@bootlin.com>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Tested-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Tested-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/f4374d53/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 11/16] gpio: Replace direction_input() and direction_output()
  2021-02-05  4:22 ` [PATCH v4 11/16] gpio: Replace direction_input() and direction_output() Simon Glass
@ 2021-03-04 18:14   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:14 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:22:04PM -0700, Simon Glass wrote:

> The new update_flags() method is more flexible since it allows the
> driver to see the full flags all at once. Use that in preference to these
> two functions. Add comments to that effect.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> 
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/e591ab40/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 12/16] gpio: Use an 'ops' variable everywhere
  2021-02-05  4:22 ` [PATCH v4 12/16] gpio: Use an 'ops' variable everywhere Simon Glass
@ 2021-03-04 18:14   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:14 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:22:05PM -0700, Simon Glass wrote:

> Update this driver to use the common method of putting the driver
> operations in an 'ops' variable install of calling gpio_get_ops()
> repeatedly. Make it const since operations do not change.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> 
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/ae84df4b/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 13/16] gpio: x86: Drop the deprecated methods in intel_gpio
  2021-02-05  4:22 ` [PATCH v4 13/16] gpio: x86: Drop the deprecated methods in intel_gpio Simon Glass
@ 2021-03-04 18:15   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:15 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:22:06PM -0700, Simon Glass wrote:

> We don't need to implement direction_input() and direction_output()
> anymore. Drop them and use update_flags() instead.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/ec39eabc/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 14/16] gpio: sandbox: Track whether a GPIO is driven
  2021-02-05  4:22 ` [PATCH v4 14/16] gpio: sandbox: Track whether a GPIO is driven Simon Glass
@ 2021-03-04 18:15   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:15 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:22:07PM -0700, Simon Glass wrote:

> Add a new flag to keep track of whether sandbox is driving the pin, or
> whether it is expecting an input signal. If it is driving, then the value
> of the pin is the value being driven (0 or 1). If not driving, then we
> consider the value 0, since we don't currently handle things like pull-ups
> yet.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/1bf22f5b/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 15/16] gpio: Define the log category in the uclass
  2021-02-05  4:22 ` [PATCH v4 15/16] gpio: Define the log category in the uclass Simon Glass
@ 2021-03-04 18:15   ` Tom Rini
  0 siblings, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:15 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:22:08PM -0700, Simon Glass wrote:

> This uses log_debug(), etc. but does not define the category. Fix this.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/0f4e8685/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 16/16] gpio: Add a way to read 3-way strapping pins
  2021-02-05  4:22 ` [PATCH v4 16/16] gpio: Add a way to read 3-way strapping pins Simon Glass
  2021-02-08 18:13   ` Patrick DELAUNAY
@ 2021-03-04 18:15   ` Tom Rini
  1 sibling, 0 replies; 42+ messages in thread
From: Tom Rini @ 2021-03-04 18:15 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 04, 2021 at 09:22:09PM -0700, Simon Glass wrote:

> Using the internal vs. external pull resistors it is possible to get
> 27 different combinations from 3 strapping pins. Add an implementation
> of this.
> 
> This involves updating the sandbox GPIO driver to model external and
> (weaker) internal pull resistors. The get_value() method now takes account
> of what is driving a pin:
> 
>    sandbox: GPIOD_EXT_DRIVEN - in which case GPIO_EXT_HIGH provides the
>           value
>    outside source - in which case GPIO_EXT_PULL_UP/DOWN indicates the
>           external state and we work the final state using those flags and
>           the internal GPIOD_PULL_UP/DOWN flags
> 
> Of course the outside source does not really exist in sandbox. We are just
> modelling it for test purpose.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/next, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20210304/3b0bc7e3/attachment.sig>

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2021-03-04 18:15 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-05  4:21 [PATCH v4 00/16] gpio: Update and simplify the uclass API Simon Glass
2021-02-05  4:21 ` [PATCH v4 01/16] gpio: Disable functions not used with of-platdata Simon Glass
2021-03-04 18:13   ` Tom Rini
2021-02-05  4:21 ` [PATCH v4 02/16] dm: gpio: Rename set_dir_flags() method to update_flags() Simon Glass
2021-03-04 18:14   ` Tom Rini
2021-02-05  4:21 ` [PATCH v4 03/16] dm: gpio: Rename get_dir_flags() method to get_flags() Simon Glass
2021-03-04 18:14   ` Tom Rini
2021-02-05  4:21 ` [PATCH v4 04/16] gpio: Rename dm_gpio_get_dir_flags() to dm_gpio_get_flags() Simon Glass
2021-03-04 18:14   ` Tom Rini
2021-02-05  4:21 ` [PATCH v4 05/16] gpio: Drop dm_gpio_set_dir() Simon Glass
2021-03-03 20:39   ` Tom Rini
2021-03-04 14:22     ` Simon Glass
2021-03-04 15:09       ` Tom Rini
2021-02-05  4:21 ` [PATCH v4 06/16] gpio: sandbox: Rename GPIO dir_flags to flags Simon Glass
2021-03-04 18:14   ` Tom Rini
2021-02-05  4:22 ` [PATCH v4 07/16] gpio: sandbox: Use a separate flag for the value Simon Glass
2021-03-04 18:14   ` Tom Rini
2021-02-05  4:22 ` [PATCH v4 08/16] gpio: sandbox: Fully separate pin value from output value Simon Glass
2021-03-04 18:14   ` Tom Rini
2021-02-05  4:22 ` [PATCH v4 09/16] gpio: sandbox: Make sandbox_gpio_set_flags() set all flags Simon Glass
2021-03-04 18:14   ` Tom Rini
2021-02-05  4:22 ` [PATCH v4 10/16] dm: gpio: Add a way to update flags Simon Glass
2021-02-08  9:00   ` Köry Maincent
2021-02-08 17:33   ` Patrick DELAUNAY
2021-02-09  4:28     ` Simon Glass
2021-02-10  8:38       ` Patrick DELAUNAY
2021-02-13  4:17         ` Simon Glass
2021-03-04 18:14   ` Tom Rini
2021-02-05  4:22 ` [PATCH v4 11/16] gpio: Replace direction_input() and direction_output() Simon Glass
2021-03-04 18:14   ` Tom Rini
2021-02-05  4:22 ` [PATCH v4 12/16] gpio: Use an 'ops' variable everywhere Simon Glass
2021-03-04 18:14   ` Tom Rini
2021-02-05  4:22 ` [PATCH v4 13/16] gpio: x86: Drop the deprecated methods in intel_gpio Simon Glass
2021-03-04 18:15   ` Tom Rini
2021-02-05  4:22 ` [PATCH v4 14/16] gpio: sandbox: Track whether a GPIO is driven Simon Glass
2021-03-04 18:15   ` Tom Rini
2021-02-05  4:22 ` [PATCH v4 15/16] gpio: Define the log category in the uclass Simon Glass
2021-03-04 18:15   ` Tom Rini
2021-02-05  4:22 ` [PATCH v4 16/16] gpio: Add a way to read 3-way strapping pins Simon Glass
2021-02-08 18:13   ` Patrick DELAUNAY
2021-02-08 23:41     ` Simon Glass
2021-03-04 18:15   ` Tom Rini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.