gpio: mmio: Also read bits that are zero
authorLinus Walleij <linus.walleij@linaro.org>
Tue, 16 Jan 2018 08:51:51 +0000 (09:51 +0100)
committerLinus Walleij <linus.walleij@linaro.org>
Tue, 16 Jan 2018 22:42:36 +0000 (23:42 +0100)
commit07c7b6a52503ac13ae357a8b3ef3456590a64b65
treef141127f3a64737257a7b0e4a4933f1263f8fe7e
parenta8750ddca918032d6349adbf9a4b6555e7db20da
gpio: mmio: Also read bits that are zero

The code for .get_multiple() has bugs:

1. The simple .get_multiple() just reads a register, masks it
and sets the return value. This is not correct: we only want to
assign values (whether 0 or 1) to the bits that are set in the
mask. Fix this by using &= ~mask to clear all bits in the mask
and then |= val & mask to set the corresponding bits from the
read.

2. The bgpio_get_multiple_be() call has a similar problem: it
uses the |= operator to set the bits, so only the bits in the
mask are affected, but it misses to clear all returned bits
from the mask initially, so some bits will be returned
erroneously set to 1.

3. The bgpio_get_set_multiple() again fails to clear the bits
from the mask.

4. find_next_bit() wasn't handled correctly, use a totally
different approach for one function and change the other
function to follow the design pattern of assigning the first
bit to -1, then use bit + 1 in the for loop and < num_iterations
as break condition.

Fixes: 80057cb417b2 ("gpio-mmio: Use the new .get_multiple() callback")
Cc: Bartosz Golaszewski <brgl@bgdev.pl>
Reported-by: Clemens Gruber <clemens.gruber@pqgruber.com>
Tested-by: Clemens Gruber <clemens.gruber@pqgruber.com>
Reported-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpio-mmio.c