diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2016-11-13 17:02:44 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-11-15 04:29:41 -0500 |
commit | ad17731d7bd1c379f83d4bde844169588441266f (patch) | |
tree | 6e3316e335bca66714dbf3a092ddbaa5e7a8f756 /drivers/gpio | |
parent | 24b35ed9a84ab1e7ad96c67434841120ca7fbf36 (diff) |
gpio: clamp values on gpio[d]_direction_output()
I saw weird values != [0,1] being passed down to drivers
in their .set_direction_output() callbacks. Go over the
gpiolib and make sure to hammer it to [0,1] before hitting
the driver to avoid undesired side effects.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpiolib.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f0fc3a0d37c8..b7452c5223be 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -2150,6 +2150,7 @@ EXPORT_SYMBOL_GPL(gpiod_direction_input); | |||
2150 | static int _gpiod_direction_output_raw(struct gpio_desc *desc, int value) | 2150 | static int _gpiod_direction_output_raw(struct gpio_desc *desc, int value) |
2151 | { | 2151 | { |
2152 | struct gpio_chip *gc = desc->gdev->chip; | 2152 | struct gpio_chip *gc = desc->gdev->chip; |
2153 | int val = !!value; | ||
2153 | int ret; | 2154 | int ret; |
2154 | 2155 | ||
2155 | /* GPIOs used for IRQs shall not be set as output */ | 2156 | /* GPIOs used for IRQs shall not be set as output */ |
@@ -2169,7 +2170,7 @@ static int _gpiod_direction_output_raw(struct gpio_desc *desc, int value) | |||
2169 | goto set_output_value; | 2170 | goto set_output_value; |
2170 | } | 2171 | } |
2171 | /* Emulate open drain by not actively driving the line high */ | 2172 | /* Emulate open drain by not actively driving the line high */ |
2172 | if (value) | 2173 | if (val) |
2173 | return gpiod_direction_input(desc); | 2174 | return gpiod_direction_input(desc); |
2174 | } | 2175 | } |
2175 | else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) { | 2176 | else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) { |
@@ -2180,7 +2181,7 @@ static int _gpiod_direction_output_raw(struct gpio_desc *desc, int value) | |||
2180 | goto set_output_value; | 2181 | goto set_output_value; |
2181 | } | 2182 | } |
2182 | /* Emulate open source by not actively driving the line low */ | 2183 | /* Emulate open source by not actively driving the line low */ |
2183 | if (!value) | 2184 | if (!val) |
2184 | return gpiod_direction_input(desc); | 2185 | return gpiod_direction_input(desc); |
2185 | } else { | 2186 | } else { |
2186 | /* Make sure to disable open drain/source hardware, if any */ | 2187 | /* Make sure to disable open drain/source hardware, if any */ |
@@ -2198,10 +2199,10 @@ set_output_value: | |||
2198 | return -EIO; | 2199 | return -EIO; |
2199 | } | 2200 | } |
2200 | 2201 | ||
2201 | ret = gc->direction_output(gc, gpio_chip_hwgpio(desc), value); | 2202 | ret = gc->direction_output(gc, gpio_chip_hwgpio(desc), val); |
2202 | if (!ret) | 2203 | if (!ret) |
2203 | set_bit(FLAG_IS_OUT, &desc->flags); | 2204 | set_bit(FLAG_IS_OUT, &desc->flags); |
2204 | trace_gpio_value(desc_to_gpio(desc), 0, value); | 2205 | trace_gpio_value(desc_to_gpio(desc), 0, val); |
2205 | trace_gpio_direction(desc_to_gpio(desc), 0, ret); | 2206 | trace_gpio_direction(desc_to_gpio(desc), 0, ret); |
2206 | return ret; | 2207 | return ret; |
2207 | } | 2208 | } |
@@ -2241,6 +2242,8 @@ int gpiod_direction_output(struct gpio_desc *desc, int value) | |||
2241 | VALIDATE_DESC(desc); | 2242 | VALIDATE_DESC(desc); |
2242 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | 2243 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) |
2243 | value = !value; | 2244 | value = !value; |
2245 | else | ||
2246 | value = !!value; | ||
2244 | return _gpiod_direction_output_raw(desc, value); | 2247 | return _gpiod_direction_output_raw(desc, value); |
2245 | } | 2248 | } |
2246 | EXPORT_SYMBOL_GPL(gpiod_direction_output); | 2249 | EXPORT_SYMBOL_GPL(gpiod_direction_output); |
@@ -3094,7 +3097,7 @@ static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, | |||
3094 | /* Process flags */ | 3097 | /* Process flags */ |
3095 | if (dflags & GPIOD_FLAGS_BIT_DIR_OUT) | 3098 | if (dflags & GPIOD_FLAGS_BIT_DIR_OUT) |
3096 | status = gpiod_direction_output(desc, | 3099 | status = gpiod_direction_output(desc, |
3097 | dflags & GPIOD_FLAGS_BIT_DIR_VAL); | 3100 | !!(dflags & GPIOD_FLAGS_BIT_DIR_VAL)); |
3098 | else | 3101 | else |
3099 | status = gpiod_direction_input(desc); | 3102 | status = gpiod_direction_input(desc); |
3100 | 3103 | ||