linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC] gpio: add set_active_low() function to gpio_chip
@ 2015-03-18 20:16 David Cohen
  2015-03-19  2:07 ` Alexandre Courbot
  2015-03-27  8:45 ` Linus Walleij
  0 siblings, 2 replies; 4+ messages in thread
From: David Cohen @ 2015-03-18 20:16 UTC (permalink / raw)
  To: linus.walleij, gnurou; +Cc: linux-gpio, linux-kernel, David Cohen

Some gpio controllers are capable of programming its pins' active-low
state. Let's add this new gpio_chip function for such cases and use it
in gpiolib.

When set_active_low() is implemented, we no longer need to do soft flips
on values from non-raw get functions.

Signed-off-by: David Cohen <david.a.cohen@linux.intel.com>
---

Hi,

This is a RFC, not meant for integration (yet).

We have a GPIO controller that is capable of inverting the GPIO logical value
on hardware using a register (and GPIO voltage level if configured for output):
- If GPIO pin is configured for input, only the logical value is affected: the
  GPIO level stays the same but the read values are inverted (it affects even
  interrupt event triggers).
- If GPIO pin is configured for output, the GPIO level is also inverted.

Is it acceptable to expose this functionality via new gpio chip operation
set_active_low()?

Comments are welcome.

Br, David
---

 drivers/gpio/gpiolib-sysfs.c | 4 ++++
 drivers/gpio/gpiolib.c       | 6 ++++--
 include/linux/gpio/driver.h  | 2 ++
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index 7722ed53bd65..316a1d008cad 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -289,11 +289,15 @@ static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store);
 static int sysfs_set_active_low(struct gpio_desc *desc, struct device *dev,
 				int value)
 {
+	struct gpio_chip	*chip = desc->chip;
 	int			status = 0;
 
 	if (!!test_bit(FLAG_ACTIVE_LOW, &desc->flags) == !!value)
 		return 0;
 
+	if (chip->set_active_low)
+		chip->set_active_low(chip, gpio_chip_hwgpio(desc), value);
+
 	if (value)
 		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
 	else
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 1ca9295b2c10..028a0d34ddab 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1196,7 +1196,8 @@ int gpiod_get_value(const struct gpio_desc *desc)
 	WARN_ON(desc->chip->can_sleep);
 
 	value = _gpiod_get_raw_value(desc);
-	if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
+	if (!desc->chip->set_active_low &&
+	    test_bit(FLAG_ACTIVE_LOW, &desc->flags))
 		value = !value;
 
 	return value;
@@ -1550,7 +1551,8 @@ int gpiod_get_value_cansleep(const struct gpio_desc *desc)
 		return 0;
 
 	value = _gpiod_get_raw_value(desc);
-	if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
+	if (!desc->chip->set_active_low &&
+	    test_bit(FLAG_ACTIVE_LOW, &desc->flags))
 		value = !value;
 
 	return value;
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index c497c62889d1..2d665352fd69 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -90,6 +90,8 @@ struct gpio_chip {
 						unsigned offset);
 	void			(*set)(struct gpio_chip *chip,
 						unsigned offset, int value);
+	void			(*set_active_low)(struct gpio_chip *chip,
+						unsigned offset, int value);
 	void			(*set_multiple)(struct gpio_chip *chip,
 						unsigned long *mask,
 						unsigned long *bits);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC] gpio: add set_active_low() function to gpio_chip
  2015-03-18 20:16 [RFC] gpio: add set_active_low() function to gpio_chip David Cohen
@ 2015-03-19  2:07 ` Alexandre Courbot
  2015-03-19 15:33   ` Stephen Warren
  2015-03-27  8:45 ` Linus Walleij
  1 sibling, 1 reply; 4+ messages in thread
From: Alexandre Courbot @ 2015-03-19  2:07 UTC (permalink / raw)
  To: David Cohen
  Cc: Linus Walleij, linux-gpio@vger.kernel.org,
	Linux Kernel Mailing List

On Thu, Mar 19, 2015 at 5:16 AM, David Cohen
<david.a.cohen@linux.intel.com> wrote:
> Some gpio controllers are capable of programming its pins' active-low
> state. Let's add this new gpio_chip function for such cases and use it
> in gpiolib.
>
> When set_active_low() is implemented, we no longer need to do soft flips
> on values from non-raw get functions.
>
> Signed-off-by: David Cohen <david.a.cohen@linux.intel.com>
> ---
>
> Hi,
>
> This is a RFC, not meant for integration (yet).
>
> We have a GPIO controller that is capable of inverting the GPIO logical value
> on hardware using a register (and GPIO voltage level if configured for output):
> - If GPIO pin is configured for input, only the logical value is affected: the
>   GPIO level stays the same but the read values are inverted (it affects even
>   interrupt event triggers).
> - If GPIO pin is configured for output, the GPIO level is also inverted.
>
> Is it acceptable to expose this functionality via new gpio chip operation
> set_active_low()?

At first I thought "why not", but then I couldn't help but ask "why?"

Handling the active low state in software is basically free and
requires no extra support. What is the benefit of handling it in
hardware that would counterbalance the complexity this adds to the
GPIO framework?

Also, wouldn't that require us to reverse this active-low logic in the
*_raw functions for them to work as expected?

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC] gpio: add set_active_low() function to gpio_chip
  2015-03-19  2:07 ` Alexandre Courbot
@ 2015-03-19 15:33   ` Stephen Warren
  0 siblings, 0 replies; 4+ messages in thread
From: Stephen Warren @ 2015-03-19 15:33 UTC (permalink / raw)
  To: Alexandre Courbot, David Cohen
  Cc: Linus Walleij, linux-gpio@vger.kernel.org,
	Linux Kernel Mailing List

On 03/18/2015 08:07 PM, Alexandre Courbot wrote:
> On Thu, Mar 19, 2015 at 5:16 AM, David Cohen
> <david.a.cohen@linux.intel.com> wrote:
>> Some gpio controllers are capable of programming its pins' active-low
>> state. Let's add this new gpio_chip function for such cases and use it
>> in gpiolib.
>>
>> When set_active_low() is implemented, we no longer need to do soft flips
>> on values from non-raw get functions.
>>
>> Signed-off-by: David Cohen <david.a.cohen@linux.intel.com>
>> ---
>>
>> Hi,
>>
>> This is a RFC, not meant for integration (yet).
>>
>> We have a GPIO controller that is capable of inverting the GPIO logical value
>> on hardware using a register (and GPIO voltage level if configured for output):
>> - If GPIO pin is configured for input, only the logical value is affected: the
>>    GPIO level stays the same but the read values are inverted (it affects even
>>    interrupt event triggers).
>> - If GPIO pin is configured for output, the GPIO level is also inverted.
>>
>> Is it acceptable to expose this functionality via new gpio chip operation
>> set_active_low()?
>
> At first I thought "why not", but then I couldn't help but ask "why?"
>
> Handling the active low state in software is basically free and
> requires no extra support. What is the benefit of handling it in
> hardware that would counterbalance the complexity this adds to the
> GPIO framework?
>
> Also, wouldn't that require us to reverse this active-low logic in the
> *_raw functions for them to work as expected?

What happens when some generic driver starts to make use of this new API 
because it's convenient? Then that API has to work everywhere, including 
on chips that don't support this feature in HW. Then, we're back to 
emulating it in SW on those platforms. Given how trivial it is to 
emulate, shouldn't we emulate it everywhere, so that the code paths are 
identical everywhere?

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC] gpio: add set_active_low() function to gpio_chip
  2015-03-18 20:16 [RFC] gpio: add set_active_low() function to gpio_chip David Cohen
  2015-03-19  2:07 ` Alexandre Courbot
@ 2015-03-27  8:45 ` Linus Walleij
  1 sibling, 0 replies; 4+ messages in thread
From: Linus Walleij @ 2015-03-27  8:45 UTC (permalink / raw)
  To: David Cohen
  Cc: Alexandre Courbot, linux-gpio@vger.kernel.org,
	linux-kernel@vger.kernel.org

On Wed, Mar 18, 2015 at 9:16 PM, David Cohen
<david.a.cohen@linux.intel.com> wrote:

> +++ b/drivers/gpio/gpiolib-sysfs.c
> @@ -289,11 +289,15 @@ static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store);
>  static int sysfs_set_active_low(struct gpio_desc *desc, struct device *dev,
>                                 int value)
>  {
> +       struct gpio_chip        *chip = desc->chip;
>         int                     status = 0;
>
>         if (!!test_bit(FLAG_ACTIVE_LOW, &desc->flags) == !!value)
>                 return 0;
>
> +       if (chip->set_active_low)
> +               chip->set_active_low(chip, gpio_chip_hwgpio(desc), value);
> +
>         if (value)
>                 set_bit(FLAG_ACTIVE_LOW, &desc->flags);

Since the only user seems to be this abominable sysfs, and since that is
definitely not on the hotpath due to context switching, this cannot possibly
gain any performance benefits.

Unless we can come up with a use case where this actually improves
performance we should just let software handle this instead.

I like to have all hardware features implemented usually, so I'm a bit
torn. But this one lacks a plausible use case. It looks like some hardware
engineers attempt to be helpful to software developers.

Any takers?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-03-27  8:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-18 20:16 [RFC] gpio: add set_active_low() function to gpio_chip David Cohen
2015-03-19  2:07 ` Alexandre Courbot
2015-03-19 15:33   ` Stephen Warren
2015-03-27  8:45 ` Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).