• Bartosz Golaszewski's avatar
    gpio: remove gpio_lock · 35b54533
    Bartosz Golaszewski authored
    The "multi-function" gpio_lock is pretty much useless with how it's used
    in GPIOLIB currently. Because many GPIO API calls can be called from all
    contexts but may also call into sleeping driver callbacks, there are
    many places with utterly broken workarounds like yielding the lock to
    call a possibly sleeping function and then re-acquiring it again without
    taking into account that the protected state may have changed.
    
    It was also used to protect several unrelated things: like individual
    descriptors AND the GPIO device list. We now serialize access to these
    two with SRCU and so can finally remove the spinlock.
    
    There is of course the question of consistency of lockless access to
    GPIO descriptors. Because we only support exclusive access to GPIOs
    (officially anyway, I'm looking at you broken
    GPIOD_FLAGS_BIT_NONEXCLUSIVE bit...) and the API contract with providers
    does not guarantee serialization, it's enough to ensure we cannot
    accidentally dereference an invalid pointer and that the state we present
    to both users and providers remains consistent. To achieve that: read the
    flags field atomically except for a few special cases. Read their current
    value before executing callback code and use this value for any subsequent
    logic. Modifying the flags depends on the particular use-case and can
    differ. For instance: when requesting a GPIO, we need to set the
    REQUESTED bit immediately so that the next user trying to request the
    same line sees -EBUSY.
    
    While at it: the allocations that used GFP_ATOMIC until this point can
    now switch to GFP_KERNEL.
    Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
    Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
    Acked-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
    35b54533
gpiolib.c 129 KB