kernel: backport gpio emulated open drain output fix
authorRussell King <linux@armlinux.org.uk>
Thu, 21 May 2020 08:57:22 +0000 (09:57 +0100)
committerPetr Štetiar <ynezz@true.cz>
Thu, 21 May 2020 10:55:31 +0000 (12:55 +0200)
Backport the GPIO emulated open drain output fix from v5.5, which is
required for the i2c-pxa backport.

Signed-off-by: Russell King <linux@armlinux.org.uk>
target/linux/generic/backport-5.4/802-v5.5-gpiolib-fix-up-emulated-open-drain-outputs.patch [new file with mode: 0644]

diff --git a/target/linux/generic/backport-5.4/802-v5.5-gpiolib-fix-up-emulated-open-drain-outputs.patch b/target/linux/generic/backport-5.4/802-v5.5-gpiolib-fix-up-emulated-open-drain-outputs.patch
new file mode 100644 (file)
index 0000000..311d4ed
--- /dev/null
@@ -0,0 +1,45 @@
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Bcc: linux@mail.armlinux.org.uk
+Cc: Linus Walleij <linus.walleij@linaro.org>,Bartosz Golaszewski <bgolaszewski@baylibre.com>,linux-gpio@vger.kernel.org
+Subject: [PATCH] gpiolib: fix up emulated open drain outputs
+MIME-Version: 1.0
+Content-Disposition: inline
+Content-Transfer-Encoding: 8bit
+Content-Type: text/plain; charset="utf-8"
+
+gpiolib has a corner case with open drain outputs that are emulated.
+When such outputs are outputting a logic 1, emulation will set the
+hardware to input mode, which will cause gpiod_get_direction() to
+report that it is in input mode. This is different from the behaviour
+with a true open-drain output.
+
+Unify the semantics here.
+
+Suggested-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+---
+ drivers/gpio/gpiolib.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index 104ed299d5ea..99d19f80440e 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -220,6 +220,14 @@ int gpiod_get_direction(struct gpio_desc *desc)
+       chip = gpiod_to_chip(desc);
+       offset = gpio_chip_hwgpio(desc);
++      /*
++       * Open drain emulation using input mode may incorrectly report
++       * input here, fix that up.
++       */
++      if (test_bit(FLAG_OPEN_DRAIN, &desc->flags) &&
++          test_bit(FLAG_IS_OUT, &desc->flags))
++              return 0;
++
+       if (!chip->get_direction)
+               return -ENOTSUPP;
+-- 
+2.20.1
+