Skip to content

Commit b440396

Browse files
warthog618Bartosz Golaszewski
authored andcommitted
gpiolib: cdev: Ignore reconfiguration without direction
linereq_set_config() behaves badly when direction is not set. The configuration validation is borrowed from linereq_create(), where, to verify the intent of the user, the direction must be set to in order to effect a change to the electrical configuration of a line. But, when applied to reconfiguration, that validation does not allow for the unset direction case, making it possible to clear flags set previously without specifying the line direction. Adding to the inconsistency, those changes are not immediately applied by linereq_set_config(), but will take effect when the line value is next get or set. For example, by requesting a configuration with no flags set, an output line with GPIO_V2_LINE_FLAG_ACTIVE_LOW and GPIO_V2_LINE_FLAG_OPEN_DRAIN set could have those flags cleared, inverting the sense of the line and changing the line drive to push-pull on the next line value set. Skip the reconfiguration of lines for which the direction is not set, and only reconfigure the lines for which direction is set. Fixes: a54756c ("gpiolib: cdev: support GPIO_V2_LINE_SET_CONFIG_IOCTL") Signed-off-by: Kent Gibson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent 9919cce commit b440396

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

drivers/gpio/gpiolib-cdev.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,20 +1534,22 @@ static long linereq_set_config(struct linereq *lr, void __user *ip)
15341534
line = &lr->lines[i];
15351535
desc = lr->lines[i].desc;
15361536
flags = gpio_v2_line_config_flags(&lc, i);
1537-
gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags);
1538-
edflags = flags & GPIO_V2_LINE_EDGE_DETECTOR_FLAGS;
15391537
/*
1540-
* Lines have to be requested explicitly for input
1541-
* or output, else the line will be treated "as is".
1538+
* Lines not explicitly reconfigured as input or output
1539+
* are left unchanged.
15421540
*/
1541+
if (!(flags & GPIO_V2_LINE_DIRECTION_FLAGS))
1542+
continue;
1543+
gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags);
1544+
edflags = flags & GPIO_V2_LINE_EDGE_DETECTOR_FLAGS;
15431545
if (flags & GPIO_V2_LINE_FLAG_OUTPUT) {
15441546
int val = gpio_v2_line_config_output_value(&lc, i);
15451547

15461548
edge_detector_stop(line);
15471549
ret = gpiod_direction_output(desc, val);
15481550
if (ret)
15491551
return ret;
1550-
} else if (flags & GPIO_V2_LINE_FLAG_INPUT) {
1552+
} else {
15511553
ret = gpiod_direction_input(desc);
15521554
if (ret)
15531555
return ret;

0 commit comments

Comments
 (0)