gpio: gpio-generic: add flag to read out output value from reg_set
authorVladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Wed, 29 Apr 2015 15:34:59 +0000 (18:34 +0300)
committerLinus Walleij <linus.walleij@linaro.org>
Mon, 11 May 2015 09:49:02 +0000 (11:49 +0200)
The change introduces BGPIOF_READ_OUTPUT_REG_SET flag for gpio-generic
GPIO chip implementation, which allows to get correct configured value
from reg_set register, input value is still get from reg_dat.

Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpio-generic.c
include/linux/basic_mmio_gpio.h

index b92a690f5765c37457147b83ecac3cb810b5641c..9bda3727fac12df7480f451057ed2513fcae2618 100644 (file)
@@ -135,6 +135,17 @@ static unsigned long bgpio_pin2mask_be(struct bgpio_chip *bgc,
        return 1 << (bgc->bits - 1 - pin);
 }
 
+static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio)
+{
+       struct bgpio_chip *bgc = to_bgpio_chip(gc);
+       unsigned long pinmask = bgc->pin2mask(bgc, gpio);
+
+       if (bgc->dir & pinmask)
+               return bgc->read_reg(bgc->reg_set) & pinmask;
+       else
+               return bgc->read_reg(bgc->reg_dat) & pinmask;
+}
+
 static int bgpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
        struct bgpio_chip *bgc = to_bgpio_chip(gc);
@@ -416,7 +427,8 @@ static int bgpio_setup_accessors(struct device *dev,
 static int bgpio_setup_io(struct bgpio_chip *bgc,
                          void __iomem *dat,
                          void __iomem *set,
-                         void __iomem *clr)
+                         void __iomem *clr,
+                         unsigned long flags)
 {
 
        bgc->reg_dat = dat;
@@ -437,7 +449,11 @@ static int bgpio_setup_io(struct bgpio_chip *bgc,
                bgc->gc.set_multiple = bgpio_set_multiple;
        }
 
-       bgc->gc.get = bgpio_get;
+       if (!(flags & BGPIOF_UNREADABLE_REG_SET) &&
+           (flags & BGPIOF_READ_OUTPUT_REG_SET))
+               bgc->gc.get = bgpio_get_set;
+       else
+               bgc->gc.get = bgpio_get;
 
        return 0;
 }
@@ -500,7 +516,7 @@ int bgpio_init(struct bgpio_chip *bgc, struct device *dev,
        bgc->gc.ngpio = bgc->bits;
        bgc->gc.request = bgpio_request;
 
-       ret = bgpio_setup_io(bgc, dat, set, clr);
+       ret = bgpio_setup_io(bgc, dat, set, clr, flags);
        if (ret)
                return ret;
 
index 0e97856b2cffafd8dc10218c95d2eae64169c17a..14eea946e6401cde3880cafc4e7c11e1264d918a 100644 (file)
@@ -74,5 +74,6 @@ int bgpio_init(struct bgpio_chip *bgc, struct device *dev,
 #define BGPIOF_UNREADABLE_REG_SET      BIT(1) /* reg_set is unreadable */
 #define BGPIOF_UNREADABLE_REG_DIR      BIT(2) /* reg_dir is unreadable */
 #define BGPIOF_BIG_ENDIAN_BYTE_ORDER   BIT(3)
+#define BGPIOF_READ_OUTPUT_REG_SET     BIT(4) /* reg_set stores output value */
 
 #endif /* __BASIC_MMIO_GPIO_H */