aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorBartosz Golaszewski <[email protected]>2025-03-11 14:19:51 +0000
committerBartosz Golaszewski <[email protected]>2025-04-07 07:00:48 +0000
commit92ac7de3175e3c17cbb76ae752b598cfb9dadf49 (patch)
treedc4eb8139c917a274af8774f15f6089ebdc16697 /drivers/gpio/gpiolib.c
parentLinux 6.15-rc1 (diff)
downloadkernel-92ac7de3175e3c17cbb76ae752b598cfb9dadf49.tar.gz
kernel-92ac7de3175e3c17cbb76ae752b598cfb9dadf49.zip
gpiolib: don't allow setting values on input lines
Some drivers as well as the character device and sysfs code check whether the line actually is in output mode before allowing the user to set a value. However, GPIO value setters now return integer values and can indicate failures. This allows us to move these checks into the core code. Reviewed-by: Linus Walleij <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bartosz Golaszewski <[email protected]>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index b8197502a5ac..8252a671d720 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -3593,6 +3593,9 @@ static int gpio_set_open_source_value_commit(struct gpio_desc *desc, bool value)
static int gpiod_set_raw_value_commit(struct gpio_desc *desc, bool value)
{
+ if (unlikely(!test_bit(FLAG_IS_OUT, &desc->flags)))
+ return -EPERM;
+
CLASS(gpio_chip_guard, guard)(desc);
if (!guard.gc)
return -ENODEV;
@@ -3664,6 +3667,12 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
if (!can_sleep)
WARN_ON(array_info->gdev->can_sleep);
+ for (i = 0; i < array_size; i++) {
+ if (unlikely(!test_bit(FLAG_IS_OUT,
+ &desc_array[i]->flags)))
+ return -EPERM;
+ }
+
guard(srcu)(&array_info->gdev->srcu);
gc = srcu_dereference(array_info->gdev->chip,
&array_info->gdev->srcu);
@@ -3723,6 +3732,9 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
int hwgpio = gpio_chip_hwgpio(desc);
int value = test_bit(i, value_bitmap);
+ if (unlikely(!test_bit(FLAG_IS_OUT, &desc->flags)))
+ return -EPERM;
+
/*
* Pins applicable for fast input but not for
* fast output processing may have been already