Commit 28735a7253a6c24364765e80a5428b4a151fccc2

Authored by David Brownell
Committed by Linus Torvalds
1 parent a836f5856a

[PATCH] gpio_direction_output() needs an initial value

It's been pointed out that output GPIOs should have an initial value, to
avoid signal glitching ...  among other things, it can be some time before
a driver is ready.  This patch corrects that oversight, fixing

 - documentation
 - platforms supporting the GPIO interface
 - users of that call (just one for now, others are pending)

There's only one user of this call for now since most platforms are still
using non-generic GPIO setup code, which in most cases already couples the
initial value with its "set output mode" request.

Note that most platforms are clear about the hardware letting the output
value be set before the pin direction is changed, but the s3c241x docs are
vague on that topic ...  so those chips might not avoid the glitches.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Andrew Victor <andrew@sanpeople.com>
Acked-by: Milan Svoboda <msvoboda@ra.rockwell.com>
Acked-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 11 changed files with 22 additions and 12 deletions Side-by-side Diff

Documentation/gpio.txt
... ... @@ -105,11 +105,14 @@
105 105  
106 106 /* set as input or output, returning 0 or negative errno */
107 107 int gpio_direction_input(unsigned gpio);
108   - int gpio_direction_output(unsigned gpio);
  108 + int gpio_direction_output(unsigned gpio, int value);
109 109  
110 110 The return value is zero for success, else a negative errno. It should
111 111 be checked, since the get/set calls don't have error returns and since
112 112 misconfiguration is possible. (These calls could sleep.)
  113 +
  114 +For output GPIOs, the value provided becomes the initial output value.
  115 +This helps avoid signal glitching during system startup.
113 116  
114 117 Setting the direction can fail if the GPIO number is invalid, or when
115 118 that particular GPIO can't be used in that mode. It's generally a bad
arch/arm/mach-at91/gpio.c
... ... @@ -215,13 +215,14 @@
215 215 }
216 216 EXPORT_SYMBOL(gpio_direction_input);
217 217  
218   -int gpio_direction_output(unsigned pin)
  218 +int gpio_direction_output(unsigned pin, int value)
219 219 {
220 220 void __iomem *pio = pin_to_controller(pin);
221 221 unsigned mask = pin_to_mask(pin);
222 222  
223 223 if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
224 224 return -EINVAL;
  225 + __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
225 226 __raw_writel(mask, pio + PIO_OER);
226 227 return 0;
227 228 }
arch/arm/mach-sa1100/generic.c
... ... @@ -153,7 +153,7 @@
153 153  
154 154 EXPORT_SYMBOL(gpio_direction_input);
155 155  
156   -int gpio_direction_output(unsigned gpio)
  156 +int gpio_direction_output(unsigned gpio, int value)
157 157 {
158 158 unsigned long flags;
159 159  
... ... @@ -161,6 +161,7 @@
161 161 return -EINVAL;
162 162  
163 163 local_irq_save(flags);
  164 + gpio_set_value(gpio, value);
164 165 GPDR |= GPIO_GPIO(gpio);
165 166 local_irq_restore(flags);
166 167 return 0;
arch/avr32/mach-at32ap/pio.c
... ... @@ -214,7 +214,7 @@
214 214 }
215 215 EXPORT_SYMBOL(gpio_direction_input);
216 216  
217   -int gpio_direction_output(unsigned int gpio)
  217 +int gpio_direction_output(unsigned int gpio, int value)
218 218 {
219 219 struct pio_device *pio;
220 220 unsigned int pin;
... ... @@ -222,6 +222,8 @@
222 222 pio = gpio_to_pio(gpio);
223 223 if (!pio)
224 224 return -ENODEV;
  225 +
  226 + gpio_set_value(gpio, value);
225 227  
226 228 pin = gpio & 0x1f;
227 229 pio_writel(pio, OER, 1 << pin);
drivers/spi/atmel_spi.c
... ... @@ -425,7 +425,7 @@
425 425 if (ret)
426 426 return ret;
427 427 spi->controller_state = (void *)npcs_pin;
428   - gpio_direction_output(npcs_pin);
  428 + gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH));
429 429 }
430 430  
431 431 dev_dbg(&spi->dev,
include/asm-arm/arch-at91/gpio.h
... ... @@ -223,7 +223,7 @@
223 223 }
224 224  
225 225 extern int gpio_direction_input(unsigned gpio);
226   -extern int gpio_direction_output(unsigned gpio);
  226 +extern int gpio_direction_output(unsigned gpio, int value);
227 227  
228 228 static inline int gpio_get_value(unsigned gpio)
229 229 {
include/asm-arm/arch-omap/gpio.h
... ... @@ -113,8 +113,9 @@
113 113 return __gpio_set_direction(gpio, 1);
114 114 }
115 115  
116   -static inline int gpio_direction_output(unsigned gpio)
  116 +static inline int gpio_direction_output(unsigned gpio, int value)
117 117 {
  118 + omap_set_gpio_dataout(gpio, value);
118 119 return __gpio_set_direction(gpio, 0);
119 120 }
120 121  
include/asm-arm/arch-pxa/gpio.h
... ... @@ -43,9 +43,9 @@
43 43 return pxa_gpio_mode(gpio | GPIO_IN);
44 44 }
45 45  
46   -static inline int gpio_direction_output(unsigned gpio)
  46 +static inline int gpio_direction_output(unsigned gpio, int value)
47 47 {
48   - return pxa_gpio_mode(gpio | GPIO_OUT);
  48 + return pxa_gpio_mode(gpio | GPIO_OUT | (value ? 0 : GPIO_DFLT_LOW));
49 49 }
50 50  
51 51 static inline int __gpio_get_value(unsigned gpio)
include/asm-arm/arch-s3c2410/gpio.h
... ... @@ -44,9 +44,11 @@
44 44 return 0;
45 45 }
46 46  
47   -static inline int gpio_direction_output(unsigned gpio)
  47 +static inline int gpio_direction_output(unsigned gpio, int value)
48 48 {
49 49 s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_OUTPUT);
  50 + /* REVISIT can we write the value first, to avoid glitching? */
  51 + s3c2410_gpio_setpin(gpio, value);
50 52 return 0;
51 53 }
52 54  
include/asm-arm/arch-sa1100/gpio.h
... ... @@ -38,7 +38,7 @@
38 38 }
39 39  
40 40 extern int gpio_direction_input(unsigned gpio);
41   -extern int gpio_direction_output(unsigned gpio);
  41 +extern int gpio_direction_output(unsigned gpio, int value);
42 42  
43 43  
44 44 static inline int gpio_get_value(unsigned gpio)
include/asm-avr32/arch-at32ap/gpio.h
... ... @@ -10,7 +10,7 @@
10 10 void gpio_free(unsigned int gpio);
11 11  
12 12 int gpio_direction_input(unsigned int gpio);
13   -int gpio_direction_output(unsigned int gpio);
  13 +int gpio_direction_output(unsigned int gpio, int value);
14 14 int gpio_get_value(unsigned int gpio);
15 15 void gpio_set_value(unsigned int gpio, int value);
16 16