diff options
author | Axel Lin <axel.lin@ingics.com> | 2014-04-07 19:59:39 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2014-04-28 15:35:09 -0400 |
commit | ef7de2625fdd40c2d26a10bf87cc1626017adc18 (patch) | |
tree | bcd0e10d8a9c19879cddf3907cd699768f1fa591 | |
parent | e45d1c80c0eee88e82751461e9cac49d9ed287bc (diff) |
gpio: zevio: Get correct gpio output value
Read gpio output value from ZEVIO_GPIO_OUTPUT.
The spin_lock is required to ensure the direction is not changed before reading
input/ouput value.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/gpio/gpio-zevio.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/gpio/gpio-zevio.c b/drivers/gpio/gpio-zevio.c index 7184f4577848..6270f755d0ed 100644 --- a/drivers/gpio/gpio-zevio.c +++ b/drivers/gpio/gpio-zevio.c | |||
@@ -81,9 +81,15 @@ static inline void zevio_gpio_port_set(struct zevio_gpio *c, unsigned pin, | |||
81 | static int zevio_gpio_get(struct gpio_chip *chip, unsigned pin) | 81 | static int zevio_gpio_get(struct gpio_chip *chip, unsigned pin) |
82 | { | 82 | { |
83 | struct zevio_gpio *controller = to_zevio_gpio(chip); | 83 | struct zevio_gpio *controller = to_zevio_gpio(chip); |
84 | u32 val, dir; | ||
84 | 85 | ||
85 | /* Only reading allowed, so no spinlock needed */ | 86 | spin_lock(&controller->lock); |
86 | u32 val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_INPUT); | 87 | dir = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_DIRECTION); |
88 | if (dir & BIT(ZEVIO_GPIO_BIT(pin))) | ||
89 | val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_INPUT); | ||
90 | else | ||
91 | val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_OUTPUT); | ||
92 | spin_unlock(&controller->lock); | ||
87 | 93 | ||
88 | return (val >> ZEVIO_GPIO_BIT(pin)) & 0x1; | 94 | return (val >> ZEVIO_GPIO_BIT(pin)) & 0x1; |
89 | } | 95 | } |