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
