summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Paukrt <tomaspaukrt@email.cz>2024-08-28 15:09:48 +0200
committerFabio Estevam <festevam@gmail.com>2024-08-30 22:32:29 -0300
commit75e8b677b7cc9a4ffddcf90d5c41afa7b7a19658 (patch)
tree8e0d52740705b73eb3c8d7b0337452f003ca5a4d
parent61f64757ac41cabfd19c3bf8cee20f78ea9c0cfe (diff)
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 https://github.com/nxp-imx/uboot-imx/commit/4afc3f90943c6b117f79b66d2cd04e64f437b0c2 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>
-rw-r--r--drivers/gpio/mxc_gpio.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c
index cac6b32b279..28176e15b7d 100644
--- a/drivers/gpio/mxc_gpio.c
+++ b/drivers/gpio/mxc_gpio.c
@@ -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 */