summaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-zevio.c
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@ingics.com>2014-04-08 01:59:39 +0200
committerLinus Walleij <linus.walleij@linaro.org>2014-04-28 21:35:09 +0200
commitef7de2625fdd40c2d26a10bf87cc1626017adc18 (patch)
treebcd0e10d8a9c19879cddf3907cd699768f1fa591 /drivers/gpio/gpio-zevio.c
parentgpio: put GPIO IRQs into their own lock class (diff)
downloadlinux-ef7de2625fdd40c2d26a10bf87cc1626017adc18.tar.xz
linux-ef7de2625fdd40c2d26a10bf87cc1626017adc18.zip
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>
Diffstat (limited to 'drivers/gpio/gpio-zevio.c')
-rw-r--r--drivers/gpio/gpio-zevio.c10
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,
static int zevio_gpio_get(struct gpio_chip *chip, unsigned pin)
{
struct zevio_gpio *controller = to_zevio_gpio(chip);
+ u32 val, dir;
- /* Only reading allowed, so no spinlock needed */
- u32 val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_INPUT);
+ spin_lock(&controller->lock);
+ dir = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_DIRECTION);
+ if (dir & BIT(ZEVIO_GPIO_BIT(pin)))
+ val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_INPUT);
+ else
+ val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_OUTPUT);
+ spin_unlock(&controller->lock);
return (val >> ZEVIO_GPIO_BIT(pin)) & 0x1;
}