]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
gpio: xilinx: Fix bug where the wrong GPIO register is written to
authorPaul Thomas <pthomas8589@gmail.com>
Sat, 25 Jan 2020 22:14:10 +0000 (17:14 -0500)
committerSeth Forshee <seth.forshee@canonical.com>
Thu, 20 Feb 2020 14:35:31 +0000 (08:35 -0600)
BugLink: https://bugs.launchpad.net/bugs/1864046
commit c3afa804c58e5c30ac63858b527fffadc88bce82 upstream.

Care is taken with "index", however with the current version
the actual xgpio_writereg is using index for data but
xgpio_regoffset(chip, i) for the offset. And since i is already
incremented it is incorrect. This patch fixes it so that index
is used for the offset too.

Cc: stable@vger.kernel.org
Signed-off-by: Paul Thomas <pthomas8589@gmail.com>
Link: https://lore.kernel.org/r/20200125221410.8022-1-pthomas8589@gmail.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 4267ba3bac6df461a50cefa5c586e598af77c479)
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
drivers/gpio/gpio-xilinx.c

index a9748b5198e634f6a0938cc8bdff61f14a120cbc..67f9f82e0db0ef49a59f073bdb52b982411f29ac 100644 (file)
@@ -147,9 +147,10 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
        for (i = 0; i < gc->ngpio; i++) {
                if (*mask == 0)
                        break;
+               /* Once finished with an index write it out to the register */
                if (index !=  xgpio_index(chip, i)) {
                        xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
-                                      xgpio_regoffset(chip, i),
+                                      index * XGPIO_CHANNEL_OFFSET,
                                       chip->gpio_state[index]);
                        spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
                        index =  xgpio_index(chip, i);
@@ -165,7 +166,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
        }
 
        xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
-                      xgpio_regoffset(chip, i), chip->gpio_state[index]);
+                      index * XGPIO_CHANNEL_OFFSET, chip->gpio_state[index]);
 
        spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
 }