Skip to content

Commit 95dd1e3

Browse files
BoergeStBartosz Golaszewski
authored andcommitted
gpiolib: sysfs: Fix error handling on failed export
If gpio_set_transitory() fails, we should free the GPIO again. Most notably, the flag FLAG_REQUESTED has previously been set in gpiod_request_commit(), and should be reset on failure. To my knowledge, this does not affect any current users, since the gpio_set_transitory() mainly returns 0 and -ENOTSUPP, which is converted to 0. However the gpio_set_transitory() function calles the .set_config() function of the corresponding GPIO chip and there are some GPIO drivers in which some (unlikely) branches return other values like -EPROBE_DEFER, and -EINVAL. In these cases, the above mentioned FLAG_REQUESTED would not be reset, which results in the pin being blocked until the next reboot. Fixes: e10f72b ("gpio: gpiolib: Generalise state persistence beyond sleep") Signed-off-by: Boerge Struempfel <boerge.struempfel@gmail.com> Reviewed-by: Andy Shevchenko <andy@kernel.org> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
1 parent b85ea95 commit 95dd1e3

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

drivers/gpio/gpiolib-sysfs.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -474,14 +474,17 @@ static ssize_t export_store(const struct class *class,
474474
goto done;
475475

476476
status = gpiod_set_transitory(desc, false);
477-
if (!status) {
478-
status = gpiod_export(desc, true);
479-
if (status < 0)
480-
gpiod_free(desc);
481-
else
482-
set_bit(FLAG_SYSFS, &desc->flags);
477+
if (status) {
478+
gpiod_free(desc);
479+
goto done;
483480
}
484481

482+
status = gpiod_export(desc, true);
483+
if (status < 0)
484+
gpiod_free(desc);
485+
else
486+
set_bit(FLAG_SYSFS, &desc->flags);
487+
485488
done:
486489
if (status)
487490
pr_debug("%s: status %d\n", __func__, status);

0 commit comments

Comments
 (0)