• Linus Walleij's avatar
    gpio: mmio: Also read bits that are zero · 07c7b6a5
    Linus Walleij authored
    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: 80057cb4 ("gpio-mmio: Use the new .get_multiple() callback")
    Cc: Bartosz Golaszewski <brgl@bgdev.pl>
    Reported-by: default avatarClemens Gruber <clemens.gruber@pqgruber.com>
    Tested-by: default avatarClemens Gruber <clemens.gruber@pqgruber.com>
    Reported-by: default avatarLukas Wunner <lukas@wunner.de>
    Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
    07c7b6a5
gpio-mmio.c 19.4 KB