summaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorJan Kotas <jank@cadence.com>2019-04-01 10:09:42 +0100
committerLinus Walleij <linus.walleij@linaro.org>2019-04-05 00:04:28 +0700
commit4f2f95e9a81299266a4a4f771ac6eb9395528d73 (patch)
tree379954760fcedc5e8feeb77895476d26801fffe8 /drivers/gpio
parent542f36159f9466faf4bd8d776fdc79f07c048c42 (diff)
downloadlinux-4f2f95e9a81299266a4a4f771ac6eb9395528d73.tar.gz
linux-4f2f95e9a81299266a4a4f771ac6eb9395528d73.tar.bz2
linux-4f2f95e9a81299266a4a4f771ac6eb9395528d73.zip
gpio: mmio: Fix bgpio_get_set & bgpio_get_set_multiple
During my regression testing I noticed the cadence GPIO driver fails on the latest gpio for-next tree. I think the reason is this patch: commit 96cd559817f2 ("Merge branch 'devel' into for-next") Here is a part of the test log: Loopback 8 -> 24 TESTING: gpio: 488: output direction PASSED TESTING: gpio: 504: input direction PASSED TESTING: gpio: 488: 0 PASSED TESTING: gpio: 488 -> 504: 0 PASSED TESTING: gpio: 488: 1 FAILED TESTING: gpio: 488 -> 504: 1 FAILED TESTING: gpio: 488: 0 PASSED TESTING: gpio: 488 -> 504: 0 PASSED It looks like the issue is that gc->bgpio_dir has changed its meaning. It used to be set to the register value (so it was being inverted). Now it's always set to 1 for output and 0 for input. However the bgpio_get_set functions were not updated. So they invert the bit again, which means a wrong register is being accessed. This patch fixes that by removing the unnecessary inversion. Signed-off-by: Jan Kotas <jank@cadence.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-mmio.c21
1 files changed, 2 insertions, 19 deletions
diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c
index f172b4382d8d..04be18b95485 100644
--- a/drivers/gpio/gpio-mmio.c
+++ b/drivers/gpio/gpio-mmio.c
@@ -134,17 +134,6 @@ static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio)
unsigned long pinmask = bgpio_line2mask(gc, gpio);
bool dir = !!(gc->bgpio_dir & pinmask);
- /*
- * If the direction is OUT we read the value from the SET
- * register, and if the direction is IN we read the value
- * from the DAT register.
- *
- * If the direction bits are inverted, naturally this gets
- * inverted too.
- */
- if (gc->bgpio_dir_inverted)
- dir = !dir;
-
if (dir)
return !!(gc->read_reg(gc->reg_set) & pinmask);
else
@@ -164,14 +153,8 @@ static int bgpio_get_set_multiple(struct gpio_chip *gc, unsigned long *mask,
/* Make sure we first clear any bits that are zero when we read the register */
*bits &= ~*mask;
- /* Exploit the fact that we know which directions are set */
- if (gc->bgpio_dir_inverted) {
- set_mask = *mask & ~gc->bgpio_dir;
- get_mask = *mask & gc->bgpio_dir;
- } else {
- set_mask = *mask & gc->bgpio_dir;
- get_mask = *mask & ~gc->bgpio_dir;
- }
+ set_mask = *mask & gc->bgpio_dir;
+ get_mask = *mask & ~gc->bgpio_dir;
if (set_mask)
*bits |= gc->read_reg(gc->reg_set) & set_mask;