mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
gpiolib: rework the wrapper around gpio_chip::set_multiple()
Make the existing wrapper around gpio_chip::set_multiple() consistent with the one for gpio_chip::set(): make it return int, add a lockdep assertion, warn on missing set callback and move the code a bit for better readability. Add return value checks in all call places. Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> Link: https://lore.kernel.org/r/20250220-gpio-set-retval-v2-4-bc4cfd38dae3@linaro.org Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
This commit is contained in:
parent
d36058b89a
commit
9b40731275
|
|
@ -3582,21 +3582,33 @@ static int gpiod_set_raw_value_commit(struct gpio_desc *desc, bool value)
|
||||||
* defines which outputs are to be changed
|
* defines which outputs are to be changed
|
||||||
* @bits: bit value array; one bit per output; BITS_PER_LONG bits per word
|
* @bits: bit value array; one bit per output; BITS_PER_LONG bits per word
|
||||||
* defines the values the outputs specified by mask are to be set to
|
* defines the values the outputs specified by mask are to be set to
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, negative error number on failure.
|
||||||
*/
|
*/
|
||||||
static void gpio_chip_set_multiple(struct gpio_chip *gc,
|
static int gpiochip_set_multiple(struct gpio_chip *gc,
|
||||||
unsigned long *mask, unsigned long *bits)
|
unsigned long *mask, unsigned long *bits)
|
||||||
{
|
{
|
||||||
|
unsigned int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
lockdep_assert_held(&gc->gpiodev->srcu);
|
lockdep_assert_held(&gc->gpiodev->srcu);
|
||||||
|
|
||||||
|
if (WARN_ON(unlikely(!gc->set_multiple && !gc->set)))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (gc->set_multiple) {
|
if (gc->set_multiple) {
|
||||||
gc->set_multiple(gc, mask, bits);
|
gc->set_multiple(gc, mask, bits);
|
||||||
} else {
|
return 0;
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
/* set outputs if the corresponding mask bit is set */
|
|
||||||
for_each_set_bit(i, mask, gc->ngpio)
|
|
||||||
gpiochip_set(gc, i, test_bit(i, bits));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set outputs if the corresponding mask bit is set */
|
||||||
|
for_each_set_bit(i, mask, gc->ngpio) {
|
||||||
|
ret = gpiochip_set(gc, i, test_bit(i, bits));
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gpiod_set_array_value_complex(bool raw, bool can_sleep,
|
int gpiod_set_array_value_complex(bool raw, bool can_sleep,
|
||||||
|
|
@ -3606,7 +3618,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
|
||||||
unsigned long *value_bitmap)
|
unsigned long *value_bitmap)
|
||||||
{
|
{
|
||||||
struct gpio_chip *gc;
|
struct gpio_chip *gc;
|
||||||
int i = 0;
|
int i = 0, ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate array_info against desc_array and its size.
|
* Validate array_info against desc_array and its size.
|
||||||
|
|
@ -3629,7 +3641,10 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
|
||||||
bitmap_xor(value_bitmap, value_bitmap,
|
bitmap_xor(value_bitmap, value_bitmap,
|
||||||
array_info->invert_mask, array_size);
|
array_info->invert_mask, array_size);
|
||||||
|
|
||||||
gpio_chip_set_multiple(gc, array_info->set_mask, value_bitmap);
|
ret = gpiochip_set_multiple(gc, array_info->set_mask,
|
||||||
|
value_bitmap);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
i = find_first_zero_bit(array_info->set_mask, array_size);
|
i = find_first_zero_bit(array_info->set_mask, array_size);
|
||||||
if (i == array_size)
|
if (i == array_size)
|
||||||
|
|
@ -3706,8 +3721,11 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
|
||||||
} while ((i < array_size) &&
|
} while ((i < array_size) &&
|
||||||
gpio_device_chip_cmp(desc_array[i]->gdev, guard.gc));
|
gpio_device_chip_cmp(desc_array[i]->gdev, guard.gc));
|
||||||
/* push collected bits to outputs */
|
/* push collected bits to outputs */
|
||||||
if (count != 0)
|
if (count != 0) {
|
||||||
gpio_chip_set_multiple(guard.gc, mask, bits);
|
ret = gpiochip_set_multiple(guard.gc, mask, bits);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (mask != fastpath_mask)
|
if (mask != fastpath_mask)
|
||||||
bitmap_free(mask);
|
bitmap_free(mask);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user