From: Maud Spierings <[email protected]>

Make _get_value() read back the dr register instead of the psr register
when the direction is set to output. Now _get_value() can actually read
the state of an output gpio instead of being always low.

Signed-off-by: Maud Spierings <[email protected]>

---
inspired by similar logic being used in u-boot and Linux
---
 drivers/gpio/gpio-imx.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/gpio/gpio-imx.c b/drivers/gpio/gpio-imx.c
index d9499c66cd..bb14c56399 100644
--- a/drivers/gpio/gpio-imx.c
+++ b/drivers/gpio/gpio-imx.c
@@ -89,24 +89,27 @@ static int imx_gpio_direction_output(struct gpio_chip 
*chip, unsigned gpio, int
        return 0;
 }
 
-static int imx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+static int imx_get_direction(struct gpio_chip *chip, unsigned offset)
 {
        struct imx_gpio_chip *imxgpio = container_of(chip, struct 
imx_gpio_chip, chip);
        void __iomem *base = imxgpio->base;
-       u32 val;
-
-       val = readl(base + imxgpio->regs->psr);
+       u32 val = readl(base + imxgpio->regs->gdir);
 
-       return val & (1 << gpio) ? 1 : 0;
+       return (val & (1 << offset)) ? GPIOF_DIR_OUT : GPIOF_DIR_IN;
 }
 
-static int imx_get_direction(struct gpio_chip *chip, unsigned offset)
+static int imx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
 {
        struct imx_gpio_chip *imxgpio = container_of(chip, struct 
imx_gpio_chip, chip);
        void __iomem *base = imxgpio->base;
-       u32 val = readl(base + imxgpio->regs->gdir);
+       u32 val;
 
-       return (val & (1 << offset)) ? GPIOF_DIR_OUT : GPIOF_DIR_IN;
+       if (imx_get_direction(chip, gpio) == GPIOF_DIR_IN)
+               val = readl(base + imxgpio->regs->psr);
+       else
+               val = readl(base + imxgpio->regs->dr);
+
+       return val & (1 << gpio) ? 1 : 0;
 }
 
 static struct gpio_ops imx_gpio_ops = {

-- 
2.51.0



Reply via email to