gpio: mxc_gpio: fix reading state of GPIO pins in output mode

The PSR register works correctly for GPIO pins in input mode,
but always returns 0 for GPIO pins in output mode unless the SION
bit is set.

The DR register should be used for GPIO pins in output mode
to allow correct getting of previously set output value.

Please note that the Linux gpio-mxc driver and the NXP U-Boot mxc_gpio
driver already use the DR register for all GPIO pins in output mode:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=442b2494b17d1a4f0a14721580271eb23ebffd42
4afc3f9094

Signed-off-by: Tomas Paukrt <tomaspaukrt@email.cz>
Reviewed-by: Marek Vasut <marex@denx.de>
Reviewed-by: Fabio Estevam <festevam@gmail.com>
Tested-by: Fabio Estevam <festevam@gmail.com>
This commit is contained in:
Tomas Paukrt 2024-08-28 15:09:48 +02:00 committed by Fabio Estevam
parent 61f64757ac
commit 75e8b677b7

View file

@ -133,7 +133,10 @@ int gpio_get_value(unsigned gpio)
regs = (struct gpio_regs *)gpio_ports[port];
val = (readl(&regs->gpio_psr) >> gpio) & 0x01;
if ((readl(&regs->gpio_dir) >> gpio) & 0x01)
val = (readl(&regs->gpio_dr) >> gpio) & 0x01;
else
val = (readl(&regs->gpio_psr) >> gpio) & 0x01;
return val;
}
@ -210,7 +213,10 @@ static void mxc_gpio_bank_set_value(struct gpio_regs *regs, int offset,
static int mxc_gpio_bank_get_value(struct gpio_regs *regs, int offset)
{
return (readl(&regs->gpio_psr) >> offset) & 0x01;
if ((readl(&regs->gpio_dir) >> offset) & 0x01)
return (readl(&regs->gpio_dr) >> offset) & 0x01;
else
return (readl(&regs->gpio_psr) >> offset) & 0x01;
}
/* set GPIO pin 'gpio' as an input */