mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
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 <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20250311-gpio-set-check-output-v1-1-d971bca9e6fa@linaro.org Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
This commit is contained in:
parent
0af2f6be1b
commit
92ac7de317
3 changed files with 17 additions and 10 deletions
|
@ -1366,9 +1366,6 @@ static long linereq_set_values(struct linereq *lr, void __user *ip)
|
|||
/* scan requested lines to determine the subset to be set */
|
||||
for (num_set = 0, i = 0; i < lr->num_lines; i++) {
|
||||
if (lv.mask & BIT_ULL(i)) {
|
||||
/* setting inputs is not allowed */
|
||||
if (!test_bit(FLAG_IS_OUT, &lr->lines[i].desc->flags))
|
||||
return -EPERM;
|
||||
/* add to compacted values */
|
||||
if (lv.bits & BIT_ULL(i))
|
||||
__set_bit(num_set, vals);
|
||||
|
|
|
@ -134,16 +134,14 @@ static ssize_t value_store(struct device *dev,
|
|||
long value;
|
||||
|
||||
status = kstrtol(buf, 0, &value);
|
||||
|
||||
guard(mutex)(&data->mutex);
|
||||
|
||||
if (!test_bit(FLAG_IS_OUT, &desc->flags))
|
||||
return -EPERM;
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
gpiod_set_value_cansleep(desc, value);
|
||||
guard(mutex)(&data->mutex);
|
||||
|
||||
status = gpiod_set_value_cansleep(desc, value);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue