FAILED: patch "[PATCH] gpiolib: don't clear FLAG_IS_OUT when emulating" failed to apply to 4.9-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From e735244e2cf068f98b6384681a38993e0517a838 Mon Sep 17 00:00:00 2001
From: Bartosz Golaszewski <[email protected]>
Date: Tue, 1 Oct 2019 11:44:53 +0200
Subject: [PATCH] gpiolib: don't clear FLAG_IS_OUT when emulating
open-drain/open-source
When emulating open-drain/open-source by not actively driving the output lines - we're simply changing their mode to input. This is wrong as it will then make it impossible to change the value of such line - it's now considered to actually be in input mode. If we want to still use the direction_input() callback for simplicity then we need to set FLAG_IS_OUT manually in gpiod_direction_output() and not clear it in gpio_set_open_drain_value_commit() and gpio_set_open_source_value_commit().
drivers/gpio/gpiolib.c +19 -8
@@ -3070,8 +3070,10 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)if (!ret) goto set_output_value;/* Emulate open drain by not actively driving the line high */ -if (value) -return gpiod_direction_input (desc); +if (value) { + ret =gpiod_direction_input (desc); + goto set_output_flag; + } }else if (test_bit (FLAG_OPEN_SOURCE , &desc->flags)) { ret = gpio_set_config(gc, gpio_chip_hwgpio(desc),
@@ -3079,8 +3081,10 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)if (!ret) goto set_output_value;/* Emulate open source by not actively driving the line low */ -if (!value) -return gpiod_direction_input (desc); +if (!value) { + ret =gpiod_direction_input (desc); + goto set_output_flag; + } }else {gpio_set_config (gc,gpio_chip_hwgpio (desc),PIN_CONFIG_DRIVE_PUSH_PULL );
@@ -3088,6 +3092,17 @@ int gpiod_direction_output(struct gpio_desc *desc, int value) set_output_value:return gpiod_direction_output_raw_commit (desc, value); + +set_output_flag: +/* +* When emulating open-source or open-drain functionalities by not +* actively driving the line (setting mode to input) we still need to +* set the IS_OUT flag or otherwise we won't be able to set the line +* value anymore. +*/ +if (ret ==0 ) +set_bit (FLAG_IS_OUT , &desc->flags); +return ret; }EXPORT_SYMBOL_GPL (gpiod_direction_output);
@@ -3448,8 +3463,6 @@ static void gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value)if (value) { ret = chip->direction_input (chip, offset); -if (!ret) -clear_bit (FLAG_IS_OUT , &desc->flags); }else { ret = chip->direction_output (chip, offset,0 );if (!ret)
@@ -3479,8 +3492,6 @@ static void gpio_set_open_source_value_commit(struct gpio_desc *desc, bool valueset_bit (FLAG_IS_OUT , &desc->flags); }else { ret = chip->direction_input (chip, offset); -if (!ret) -clear_bit (FLAG_IS_OUT , &desc->flags); }trace_gpio_direction (desc_to_gpio (desc), !value, ret);if (ret <0 )