Skip to content

Commit 9b40731

Browse files
author
Bartosz Golaszewski
committed
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 <[email protected]> Acked-by: Uwe Kleine-König <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent d36058b commit 9b40731

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

drivers/gpio/gpiolib.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3582,21 +3582,33 @@ static int gpiod_set_raw_value_commit(struct gpio_desc *desc, bool value)
35823582
* defines which outputs are to be changed
35833583
* @bits: bit value array; one bit per output; BITS_PER_LONG bits per word
35843584
* defines the values the outputs specified by mask are to be set to
3585+
*
3586+
* Returns: 0 on success, negative error number on failure.
35853587
*/
3586-
static void gpio_chip_set_multiple(struct gpio_chip *gc,
3587-
unsigned long *mask, unsigned long *bits)
3588+
static int gpiochip_set_multiple(struct gpio_chip *gc,
3589+
unsigned long *mask, unsigned long *bits)
35883590
{
3591+
unsigned int i;
3592+
int ret;
3593+
35893594
lockdep_assert_held(&gc->gpiodev->srcu);
35903595

3596+
if (WARN_ON(unlikely(!gc->set_multiple && !gc->set)))
3597+
return -EOPNOTSUPP;
3598+
35913599
if (gc->set_multiple) {
35923600
gc->set_multiple(gc, mask, bits);
3593-
} else {
3594-
unsigned int i;
3601+
return 0;
3602+
}
35953603

3596-
/* set outputs if the corresponding mask bit is set */
3597-
for_each_set_bit(i, mask, gc->ngpio)
3598-
gpiochip_set(gc, i, test_bit(i, bits));
3604+
/* set outputs if the corresponding mask bit is set */
3605+
for_each_set_bit(i, mask, gc->ngpio) {
3606+
ret = gpiochip_set(gc, i, test_bit(i, bits));
3607+
if (ret)
3608+
break;
35993609
}
3610+
3611+
return ret;
36003612
}
36013613

36023614
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,
36063618
unsigned long *value_bitmap)
36073619
{
36083620
struct gpio_chip *gc;
3609-
int i = 0;
3621+
int i = 0, ret;
36103622

36113623
/*
36123624
* Validate array_info against desc_array and its size.
@@ -3629,7 +3641,10 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
36293641
bitmap_xor(value_bitmap, value_bitmap,
36303642
array_info->invert_mask, array_size);
36313643

3632-
gpio_chip_set_multiple(gc, array_info->set_mask, value_bitmap);
3644+
ret = gpiochip_set_multiple(gc, array_info->set_mask,
3645+
value_bitmap);
3646+
if (ret)
3647+
return ret;
36333648

36343649
i = find_first_zero_bit(array_info->set_mask, array_size);
36353650
if (i == array_size)
@@ -3706,8 +3721,11 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
37063721
} while ((i < array_size) &&
37073722
gpio_device_chip_cmp(desc_array[i]->gdev, guard.gc));
37083723
/* push collected bits to outputs */
3709-
if (count != 0)
3710-
gpio_chip_set_multiple(guard.gc, mask, bits);
3724+
if (count != 0) {
3725+
ret = gpiochip_set_multiple(guard.gc, mask, bits);
3726+
if (ret)
3727+
return ret;
3728+
}
37113729

37123730
if (mask != fastpath_mask)
37133731
bitmap_free(mask);

0 commit comments

Comments
 (0)