diff options
author | Johan Hovold <johan@kernel.org> | 2016-07-03 18:32:05 +0200 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-07-04 16:51:29 +0200 |
commit | 85b03b3033fd4eba82665b3b9902c095a08cc52f (patch) | |
tree | 6903637e3ff3c9d821dd3718d12c2321df9c25bf /drivers/gpio/gpiolib-legacy.c | |
parent | 87041a58d3b19455d39baed2a5e5bb43b58fb915 (diff) |
Revert "gpiolib: Split GPIO flags parsing and GPIO configuration"
This reverts commit 923b93e451db876d1479d3e4458fce14fec31d1c.
Make sure consumers do not overwrite gpio flags for pins that have
already been claimed.
While adding support for gpio drivers to refuse a request using
unsupported flags, the order of when the requested flag was checked and
the new flags were applied was reversed to that consumers could
overwrite flags for already requested gpios.
This not only affects device-tree setups where two drivers could request
the same gpio using conflicting configurations, but also allowed user
space to clear gpio flags for already claimed pins simply by attempting
to export them through the sysfs interface. By for example clearing the
FLAG_ACTIVE_LOW flag this way, user space could effectively change the
polarity of a signal.
Reverting this change obviously prevents gpio drivers from doing sanity
checks on the flags in their request callbacks. Fortunately only one
recently added driver (gpio-tps65218 in v4.6) appears to do this, and a
follow up patch could restore this functionality through a different
interface.
Cc: stable <stable@vger.kernel.org> # 4.4
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib-legacy.c')
-rw-r--r-- | drivers/gpio/gpiolib-legacy.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/gpio/gpiolib-legacy.c b/drivers/gpio/gpiolib-legacy.c index 3a5c7011ad3b..8b830996fe02 100644 --- a/drivers/gpio/gpiolib-legacy.c +++ b/drivers/gpio/gpiolib-legacy.c @@ -28,6 +28,10 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) if (!desc && gpio_is_valid(gpio)) return -EPROBE_DEFER; + err = gpiod_request(desc, label); + if (err) + return err; + if (flags & GPIOF_OPEN_DRAIN) set_bit(FLAG_OPEN_DRAIN, &desc->flags); @@ -37,10 +41,6 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) if (flags & GPIOF_ACTIVE_LOW) set_bit(FLAG_ACTIVE_LOW, &desc->flags); - err = gpiod_request(desc, label); - if (err) - return err; - if (flags & GPIOF_DIR_IN) err = gpiod_direction_input(desc); else |