[U-Boot] [PATCH 2/2] ARM: tegra: don't enable GPIOs until direction is set

Stephen Warren swarren at wwwdotorg.org
Wed Sep 23 20:13:00 CEST 2015


From: Stephen Warren <swarren at nvidia.com>

Tegra's GPIO driver currently enables pins as GPIO as soon as they're
requested. This is not safe, since the desired direction and output value
are not yet known. This could cause a glitch on the output pins between
gpio_request() and gpio_direction_*(), depending on what values happen to
be in the GPIO controller's in/out and out-value registers vs. the final
desired configuration.

To solve this, defer enabling pins as GPIOs until some gpio_direction_*()
is invoked, and the desired configuration is explicitly programmed.

In theory this change could cause regressions, if code exists that claims
a GPIO, never explicitly sets a direction, and then gets/sets the GPIO
value based on that assumption. However, I've read through all the Tegra-
related board files and device drivers that touch GPIOs and I do not see
such buggy code anywhere.

Signed-off-by: Stephen Warren <swarren at nvidia.com>
---
 drivers/gpio/tegra_gpio.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index c0ae7719e2c9..2dfd02d62053 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -136,17 +136,6 @@ static void set_level(unsigned gpio, int high)
  * Generic_GPIO primitives.
  */
 
-static int tegra_gpio_request(struct udevice *dev, unsigned offset,
-			      const char *label)
-{
-	struct tegra_port_info *state = dev_get_priv(dev);
-
-	/* Configure as a GPIO */
-	set_config(state->base_gpio + offset, 1);
-
-	return 0;
-}
-
 /* set GPIO pin 'gpio' as an input */
 static int tegra_gpio_direction_input(struct udevice *dev, unsigned offset)
 {
@@ -155,6 +144,9 @@ static int tegra_gpio_direction_input(struct udevice *dev, unsigned offset)
 	/* Configure GPIO direction as input. */
 	set_direction(state->base_gpio + offset, 0);
 
+	/* Enable the pin as a GPIO */
+	set_config(state->base_gpio + offset, 1);
+
 	return 0;
 }
 
@@ -171,6 +163,9 @@ static int tegra_gpio_direction_output(struct udevice *dev, unsigned offset,
 	/* Configure GPIO direction as output. */
 	set_direction(gpio, 1);
 
+	/* Enable the pin as a GPIO */
+	set_config(state->base_gpio + offset, 1);
+
 	return 0;
 }
 
@@ -256,7 +251,6 @@ static int tegra_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
 }
 
 static const struct dm_gpio_ops gpio_tegra_ops = {
-	.request		= tegra_gpio_request,
 	.direction_input	= tegra_gpio_direction_input,
 	.direction_output	= tegra_gpio_direction_output,
 	.get_value		= tegra_gpio_get_value,
-- 
1.9.1



More information about the U-Boot mailing list