[PATCH 1/3] gpiolib: Add ability to get GPIO pin direction

From: Peter Tyser
Date: Thu Jan 06 2011 - 15:14:21 EST


Add a new get_direction() function to the gpio_chip structure. This is
useful so that the direction of a pin can be determined when its
exported. Previously, the direction defaulted to 'in' regardless of the
actual configuration of the GPIO pin which resulted in the 'direction'
sysfs file often being incorrect.

If a GPIO driver implements get_direction(), it is called in
gpio_request() to set the initial direction of the pin accurately.

Cc: Alek Du <alek.du@xxxxxxxxx>
Cc: Samuel Ortiz <sameo@xxxxxxxxxxxxxxx>
Cc: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx>
Cc: Eric Miao <eric.y.miao@xxxxxxxxx>
Cc: Uwe Kleine-K?nig <u.kleine-koenig@xxxxxxxxxxxxxx>
Cc: Mark Brown <broonie@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
Cc: Joe Perches <joe@xxxxxxxxxxx>
Signed-off-by: Peter Tyser <ptyser@xxxxxxxxxxx>
---
drivers/gpio/gpiolib.c | 15 ++++++++-------
include/asm-generic/gpio.h | 4 ++++
2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 649550e..0a360d8 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1062,13 +1062,6 @@ int gpiochip_add(struct gpio_chip *chip)
if (status == 0) {
for (id = base; id < base + chip->ngpio; id++) {
gpio_desc[id].chip = chip;
-
- /* REVISIT: most hardware initializes GPIOs as
- * inputs (often with pullups enabled) so power
- * usage is minimized. Linux code should set the
- * gpio direction first thing; but until it does,
- * we may expose the wrong direction in sysfs.
- */
gpio_desc[id].flags = !chip->direction_input
? (1 << FLAG_IS_OUT)
: 0;
@@ -1215,6 +1208,14 @@ int gpio_request(unsigned gpio, const char *label)
}
}

+ if (chip->get_direction) {
+ /* chip->get_direction may sleep */
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ if (chip->get_direction(chip, gpio - chip->base) > 0)
+ set_bit(FLAG_IS_OUT, &desc->flags);
+ spin_lock_irqsave(&gpio_lock, flags);
+ }
+
done:
if (status)
pr_debug("gpio_request: gpio-%d (%s) status %d\n",
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index ff5c660..7d55cf7 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -57,6 +57,8 @@ struct device_node;
* @direction_input: configures signal "offset" as input, or returns error
* @get: returns value for signal "offset"; for output signals this
* returns either the value actually sensed, or zero
+ * @get_direction: optional hook to determine if a GPIO signal is configured
+ * as an input (0) or output (1).
* @direction_output: configures signal "offset" as output, or returns error
* @set: assigns output value for signal "offset"
* @to_irq: optional hook supporting non-static gpio_to_irq() mappings;
@@ -101,6 +103,8 @@ struct gpio_chip {
unsigned offset);
int (*get)(struct gpio_chip *chip,
unsigned offset);
+ int (*get_direction)(struct gpio_chip *chip,
+ unsigned offset);
int (*direction_output)(struct gpio_chip *chip,
unsigned offset, int value);
int (*set_debounce)(struct gpio_chip *chip,
--
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/