diff mbox series

[1/4] gpiolib: add support for bias pull disable

Message ID 20220713131421.1527179-2-nuno.sa@analog.com
State New
Headers show
Series add support for bias pull-disable | expand

Commit Message

Nuno Sa July 13, 2022, 1:14 p.m. UTC
This change prepares the gpio core to look at firmware flags and set
'FLAG_BIAS_DISABLE' if necessary. It works in similar way to
'GPIO_PULL_DOWN' and 'GPIO_PULL_UP'.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
 drivers/gpio/gpiolib.c       | 8 ++++++--
 include/linux/gpio/machine.h | 1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

Comments

Andy Shevchenko July 13, 2022, 5:36 p.m. UTC | #1
On Wed, Jul 13, 2022 at 03:14:18PM +0200, Nuno Sá wrote:
> This change prepares the gpio core to look at firmware flags and set
> 'FLAG_BIAS_DISABLE' if necessary. It works in similar way to
> 'GPIO_PULL_DOWN' and 'GPIO_PULL_UP'.

...

>  	GPIO_PULL_UP			= (1 << 4),
>  	GPIO_PULL_DOWN			= (1 << 5),
> +	GPIO_PULL_DISABLE		= (1 << 6),

To me it seems superfluous. You have already two flags:
PUp
PDown
When none is set --> Pdisable
Kent Gibson July 14, 2022, 4:20 a.m. UTC | #2
On Wed, Jul 13, 2022 at 08:36:38PM +0300, Andy Shevchenko wrote:
> On Wed, Jul 13, 2022 at 03:14:18PM +0200, Nuno Sá wrote:
> > This change prepares the gpio core to look at firmware flags and set
> > 'FLAG_BIAS_DISABLE' if necessary. It works in similar way to
> > 'GPIO_PULL_DOWN' and 'GPIO_PULL_UP'.
> 
> ...
> 
> >  	GPIO_PULL_UP			= (1 << 4),
> >  	GPIO_PULL_DOWN			= (1 << 5),
> > +	GPIO_PULL_DISABLE		= (1 << 6),
> 
> To me it seems superfluous. You have already two flags:
> PUp
> PDown
> When none is set --> Pdisable
> 

Agree with Andy on this.  The FLAG_BIAS_DISABLE was added, by me, to
allow the cdev interface to support bias.  cdev requires a "don't care"
state, distinct from an explicit BIAS_DISABLE.
The FLAG_BIAS_DISABLE allows gpiolib-cdev to communicate that to
gpiolib, without altering the interpretation of the existing PULL_UP and
PULL_DOWN flags.
That is not an issue on the machine interface, where the two GPIO_PULL
flags suffice.

If you are looking for the place where FLAG_BIAS_DISABLE is set it is in
gpio_v2_line_config_flags_to_desc_flags() in gpiolib-cdev.c.

Referring to gpio_set_bias(), the only place in gpiolib the
FLAG_BIAS_DISABLE is used, if neither FLAG_PULL_UP, FLAG_PULL_DOWN,
nor FLAG_BIAS_DISABLE are set then the bias configuration remains
unchanged (the don't care case) - no change is passed to the driver.
Otherwise the corresponding PIN_CONFIG_BIAS flag is passed to the
driver.

If there are cases of drivers not fully or correctly supporting those
PIN_CONFIG_BIAS flags, then that is an issue with those drivers.

Cheers,
Kent.
Nuno Sá July 14, 2022, 7:14 a.m. UTC | #3
On Thu, 2022-07-14 at 12:20 +0800, Kent Gibson wrote:
> On Wed, Jul 13, 2022 at 08:36:38PM +0300, Andy Shevchenko wrote:
> > On Wed, Jul 13, 2022 at 03:14:18PM +0200, Nuno Sá wrote:
> > > This change prepares the gpio core to look at firmware flags and
> > > set
> > > 'FLAG_BIAS_DISABLE' if necessary. It works in similar way to
> > > 'GPIO_PULL_DOWN' and 'GPIO_PULL_UP'.
> > 
> > ...
> > 
> > >         GPIO_PULL_UP                    = (1 << 4),
> > >         GPIO_PULL_DOWN                  = (1 << 5),
> > > +       GPIO_PULL_DISABLE               = (1 << 6),
> > 
> > To me it seems superfluous. You have already two flags:
> > PUp
> > PDown
> > When none is set --> Pdisable
> > 
> 
> Agree with Andy on this.  The FLAG_BIAS_DISABLE was added, by me, to
> allow the cdev interface to support bias.  cdev requires a "don't
> care"
> state, distinct from an explicit BIAS_DISABLE.
> The FLAG_BIAS_DISABLE allows gpiolib-cdev to communicate that to
> gpiolib, without altering the interpretation of the existing PULL_UP
> and
> PULL_DOWN flags.
> That is not an issue on the machine interface, where the two
> GPIO_PULL
> flags suffice.
> 

I see, but this means we can only disable the pin BIAS through
userspace. I might be wrong but I don't see a reason why it wouldn't be
valid to do it from an in kernel path as we do for PULL-UPS and PULL-
DOWNS 

> If you are looking for the place where FLAG_BIAS_DISABLE is set it is
> in
> gpio_v2_line_config_flags_to_desc_flags() in gpiolib-cdev.c.
> 
> Referring to gpio_set_bias(), the only place in gpiolib the
> FLAG_BIAS_DISABLE is used, if neither FLAG_PULL_UP, FLAG_PULL_DOWN,
> nor FLAG_BIAS_DISABLE are set then the bias configuration remains
> unchanged (the don't care case) - no change is passed to the driver.
> Otherwise the corresponding PIN_CONFIG_BIAS flag is passed to the
> driver.
> 

Exactly, but note FLAG_BIAS_DISABLE can only be set from userspace at
this point (IIUTC). If everyone agrees that should be case, so be it.
But as I said, I just don't see why it's wrong to do it within the
kernel.

> If there are cases of drivers not fully or correctly supporting those
> PIN_CONFIG_BIAS flags, then that is an issue with those drivers.
> 

Look at my reply to Andy in the cover for more details

- Nuno Sá
Kent Gibson July 14, 2022, 8:27 a.m. UTC | #4
On Thu, Jul 14, 2022 at 09:14:21AM +0200, Nuno Sá wrote:
> On Thu, 2022-07-14 at 12:20 +0800, Kent Gibson wrote:
> > On Wed, Jul 13, 2022 at 08:36:38PM +0300, Andy Shevchenko wrote:
> > > On Wed, Jul 13, 2022 at 03:14:18PM +0200, Nuno Sá wrote:
> > > > This change prepares the gpio core to look at firmware flags and
> > > > set
> > > > 'FLAG_BIAS_DISABLE' if necessary. It works in similar way to
> > > > 'GPIO_PULL_DOWN' and 'GPIO_PULL_UP'.
> > > 
> > > ...
> > > 
> > > >         GPIO_PULL_UP                    = (1 << 4),
> > > >         GPIO_PULL_DOWN                  = (1 << 5),
> > > > +       GPIO_PULL_DISABLE               = (1 << 6),
> > > 
> > > To me it seems superfluous. You have already two flags:
> > > PUp
> > > PDown
> > > When none is set --> Pdisable
> > > 
> > 
> > Agree with Andy on this.  The FLAG_BIAS_DISABLE was added, by me, to
> > allow the cdev interface to support bias.  cdev requires a "don't
> > care"
> > state, distinct from an explicit BIAS_DISABLE.
> > The FLAG_BIAS_DISABLE allows gpiolib-cdev to communicate that to
> > gpiolib, without altering the interpretation of the existing PULL_UP
> > and
> > PULL_DOWN flags.
> > That is not an issue on the machine interface, where the two
> > GPIO_PULL
> > flags suffice.
> > 
> 
> I see, but this means we can only disable the pin BIAS through
> userspace. I might be wrong but I don't see a reason why it wouldn't be
> valid to do it from an in kernel path as we do for PULL-UPS and PULL-
> DOWNS 
> 

> > If you are looking for the place where FLAG_BIAS_DISABLE is set it is
> > in
> > gpio_v2_line_config_flags_to_desc_flags() in gpiolib-cdev.c.
> > 
> > Referring to gpio_set_bias(), the only place in gpiolib the
> > FLAG_BIAS_DISABLE is used, if neither FLAG_PULL_UP, FLAG_PULL_DOWN,
> > nor FLAG_BIAS_DISABLE are set then the bias configuration remains
> > unchanged (the don't care case) - no change is passed to the driver.
> > Otherwise the corresponding PIN_CONFIG_BIAS flag is passed to the
> > driver.
> > 
> 
> Exactly, but note FLAG_BIAS_DISABLE can only be set from userspace at
> this point (IIUTC). If everyone agrees that should be case, so be it.
> But as I said, I just don't see why it's wrong to do it within the
> kernel.
> 

Believe it or not gpiolib-cdev is part of the kernel, not userspace - it
just provides an interface to userspace.

Bias can be disabled by calling gpiod_direction_input() or
gpiod_direction_output() after setting the FLAG_BIAS_DISABLE, as
gpiolib-cdev does.

Does that work for you?

Cheers,
Kent.


> > If there are cases of drivers not fully or correctly supporting those
> > PIN_CONFIG_BIAS flags, then that is an issue with those drivers.
> > 
> 
> Look at my reply to Andy in the cover for more details
> 
> - Nuno Sá
Nuno Sá July 14, 2022, 8:47 a.m. UTC | #5
On Thu, 2022-07-14 at 16:27 +0800, Kent Gibson wrote:
> On Thu, Jul 14, 2022 at 09:14:21AM +0200, Nuno Sá wrote:
> > On Thu, 2022-07-14 at 12:20 +0800, Kent Gibson wrote:
> > > On Wed, Jul 13, 2022 at 08:36:38PM +0300, Andy Shevchenko wrote:
> > > > On Wed, Jul 13, 2022 at 03:14:18PM +0200, Nuno Sá wrote:
> > > > > This change prepares the gpio core to look at firmware flags
> > > > > and
> > > > > set
> > > > > 'FLAG_BIAS_DISABLE' if necessary. It works in similar way to
> > > > > 'GPIO_PULL_DOWN' and 'GPIO_PULL_UP'.
> > > > 
> > > > ...
> > > > 
> > > > >         GPIO_PULL_UP                    = (1 << 4),
> > > > >         GPIO_PULL_DOWN                  = (1 << 5),
> > > > > +       GPIO_PULL_DISABLE               = (1 << 6),
> > > > 
> > > > To me it seems superfluous. You have already two flags:
> > > > PUp
> > > > PDown
> > > > When none is set --> Pdisable
> > > > 
> > > 
> > > Agree with Andy on this.  The FLAG_BIAS_DISABLE was added, by me,
> > > to
> > > allow the cdev interface to support bias.  cdev requires a "don't
> > > care"
> > > state, distinct from an explicit BIAS_DISABLE.
> > > The FLAG_BIAS_DISABLE allows gpiolib-cdev to communicate that to
> > > gpiolib, without altering the interpretation of the existing
> > > PULL_UP
> > > and
> > > PULL_DOWN flags.
> > > That is not an issue on the machine interface, where the two
> > > GPIO_PULL
> > > flags suffice.
> > > 
> > 
> > I see, but this means we can only disable the pin BIAS through
> > userspace. I might be wrong but I don't see a reason why it
> > wouldn't be
> > valid to do it from an in kernel path as we do for PULL-UPS and
> > PULL-
> > DOWNS 
> > 
> 
> > > If you are looking for the place where FLAG_BIAS_DISABLE is set
> > > it is
> > > in
> > > gpio_v2_line_config_flags_to_desc_flags() in gpiolib-cdev.c.
> > > 
> > > Referring to gpio_set_bias(), the only place in gpiolib the
> > > FLAG_BIAS_DISABLE is used, if neither FLAG_PULL_UP,
> > > FLAG_PULL_DOWN,
> > > nor FLAG_BIAS_DISABLE are set then the bias configuration remains
> > > unchanged (the don't care case) - no change is passed to the
> > > driver.
> > > Otherwise the corresponding PIN_CONFIG_BIAS flag is passed to the
> > > driver.
> > > 
> > 
> > Exactly, but note FLAG_BIAS_DISABLE can only be set from userspace
> > at
> > this point (IIUTC). If everyone agrees that should be case, so be
> > it.
> > But as I said, I just don't see why it's wrong to do it within the
> > kernel.
> > 
> 
> Believe it or not gpiolib-cdev is part of the kernel, not userspace -
> it
> just provides an interface to userspace.
> 

Yes, I do know that. But don't you still need a userspace process to
open the cdev and do the ioctl()?

> Bias can be disabled by calling gpiod_direction_input() or
> gpiod_direction_output() after setting the FLAG_BIAS_DISABLE, as
> gpiolib-cdev does.
> 
> Does that work for you?
> 

I'm not seeing how would this work... We would need to make gpiod
consumers having to do this. Something like:


desc = giod_get();
set_bit(FLAG_BIAS_DISABLE, &desc->flags);
set_direction...


Having in mind that we can already specify the direction in gpiod_get,
I don't really think this is something that consumers should have to
worry. Moreover, I would say this means special devicetree properties
for all the consumers of such a gpiochip which want to disable bias...

...

Or do you have something else in mind?

- Nuno Sá
Kent Gibson July 14, 2022, noon UTC | #6
On Thu, Jul 14, 2022 at 10:47:27AM +0200, Nuno Sá wrote:
> On Thu, 2022-07-14 at 16:27 +0800, Kent Gibson wrote:
> > On Thu, Jul 14, 2022 at 09:14:21AM +0200, Nuno Sá wrote:
> > > On Thu, 2022-07-14 at 12:20 +0800, Kent Gibson wrote:
> > > > On Wed, Jul 13, 2022 at 08:36:38PM +0300, Andy Shevchenko wrote:
> > > > > On Wed, Jul 13, 2022 at 03:14:18PM +0200, Nuno Sá wrote:
> > > > > > This change prepares the gpio core to look at firmware flags
> > > > > > and
> > > > > > set
> > > > > > 'FLAG_BIAS_DISABLE' if necessary. It works in similar way to
> > > > > > 'GPIO_PULL_DOWN' and 'GPIO_PULL_UP'.
> > > > > 
> > > > > ...
> > > > > 
> > > > > >         GPIO_PULL_UP                    = (1 << 4),
> > > > > >         GPIO_PULL_DOWN                  = (1 << 5),
> > > > > > +       GPIO_PULL_DISABLE               = (1 << 6),
> > > > > 
> > > > > To me it seems superfluous. You have already two flags:
> > > > > PUp
> > > > > PDown
> > > > > When none is set --> Pdisable
> > > > > 
> > > > 
> > > > Agree with Andy on this.  The FLAG_BIAS_DISABLE was added, by me,
> > > > to
> > > > allow the cdev interface to support bias.  cdev requires a "don't
> > > > care"
> > > > state, distinct from an explicit BIAS_DISABLE.
> > > > The FLAG_BIAS_DISABLE allows gpiolib-cdev to communicate that to
> > > > gpiolib, without altering the interpretation of the existing
> > > > PULL_UP
> > > > and
> > > > PULL_DOWN flags.
> > > > That is not an issue on the machine interface, where the two
> > > > GPIO_PULL
> > > > flags suffice.
> > > > 
> > > 
> > > I see, but this means we can only disable the pin BIAS through
> > > userspace. I might be wrong but I don't see a reason why it
> > > wouldn't be
> > > valid to do it from an in kernel path as we do for PULL-UPS and
> > > PULL-
> > > DOWNS 
> > > 
> > 
> > > > If you are looking for the place where FLAG_BIAS_DISABLE is set
> > > > it is
> > > > in
> > > > gpio_v2_line_config_flags_to_desc_flags() in gpiolib-cdev.c.
> > > > 
> > > > Referring to gpio_set_bias(), the only place in gpiolib the
> > > > FLAG_BIAS_DISABLE is used, if neither FLAG_PULL_UP,
> > > > FLAG_PULL_DOWN,
> > > > nor FLAG_BIAS_DISABLE are set then the bias configuration remains
> > > > unchanged (the don't care case) - no change is passed to the
> > > > driver.
> > > > Otherwise the corresponding PIN_CONFIG_BIAS flag is passed to the
> > > > driver.
> > > > 
> > > 
> > > Exactly, but note FLAG_BIAS_DISABLE can only be set from userspace
> > > at
> > > this point (IIUTC). If everyone agrees that should be case, so be
> > > it.
> > > But as I said, I just don't see why it's wrong to do it within the
> > > kernel.
> > > 
> > 
> > Believe it or not gpiolib-cdev is part of the kernel, not userspace -
> > it
> > just provides an interface to userspace.
> > 
> 
> Yes, I do know that. But don't you still need a userspace process to
> open the cdev and do the ioctl()?
> 

Only if you want to drive the cdev interface, so not in this case.
You would not use cdev, you would use gpiolib directly.

> > Bias can be disabled by calling gpiod_direction_input() or
> > gpiod_direction_output() after setting the FLAG_BIAS_DISABLE, as
> > gpiolib-cdev does.
> > 
> > Does that work for you?
> > 
> 
> I'm not seeing how would this work... We would need to make gpiod
> consumers having to do this. Something like:
> 
> 
> desc = giod_get();
> set_bit(FLAG_BIAS_DISABLE, &desc->flags);
> set_direction...
> 
> 

In a nutshell.

If that solves your immediate problem then you need to decide what
problem your patch is trying to address.

Cheers,
Kent.
Nuno Sá July 14, 2022, 1:02 p.m. UTC | #7
On Thu, 2022-07-14 at 20:00 +0800, Kent Gibson wrote:
> On Thu, Jul 14, 2022 at 10:47:27AM +0200, Nuno Sá wrote:
> > On Thu, 2022-07-14 at 16:27 +0800, Kent Gibson wrote:
> > > On Thu, Jul 14, 2022 at 09:14:21AM +0200, Nuno Sá wrote:
> > > > On Thu, 2022-07-14 at 12:20 +0800, Kent Gibson wrote:
> > > > > On Wed, Jul 13, 2022 at 08:36:38PM +0300, Andy Shevchenko
> > > > > wrote:
> > > > > > On Wed, Jul 13, 2022 at 03:14:18PM +0200, Nuno Sá wrote:
> > > > > > > This change prepares the gpio core to look at firmware
> > > > > > > flags
> > > > > > > and
> > > > > > > set
> > > > > > > 'FLAG_BIAS_DISABLE' if necessary. It works in similar way
> > > > > > > to
> > > > > > > 'GPIO_PULL_DOWN' and 'GPIO_PULL_UP'.
> > > > > > 
> > > > > > ...
> > > > > > 
> > > > > > >         GPIO_PULL_UP                    = (1 << 4),
> > > > > > >         GPIO_PULL_DOWN                  = (1 << 5),
> > > > > > > +       GPIO_PULL_DISABLE               = (1 << 6),
> > > > > > 
> > > > > > To me it seems superfluous. You have already two flags:
> > > > > > PUp
> > > > > > PDown
> > > > > > When none is set --> Pdisable
> > > > > > 
> > > > > 
> > > > > Agree with Andy on this.  The FLAG_BIAS_DISABLE was added, by
> > > > > me,
> > > > > to
> > > > > allow the cdev interface to support bias.  cdev requires a
> > > > > "don't
> > > > > care"
> > > > > state, distinct from an explicit BIAS_DISABLE.
> > > > > The FLAG_BIAS_DISABLE allows gpiolib-cdev to communicate that
> > > > > to
> > > > > gpiolib, without altering the interpretation of the existing
> > > > > PULL_UP
> > > > > and
> > > > > PULL_DOWN flags.
> > > > > That is not an issue on the machine interface, where the two
> > > > > GPIO_PULL
> > > > > flags suffice.
> > > > > 
> > > > 
> > > > I see, but this means we can only disable the pin BIAS through
> > > > userspace. I might be wrong but I don't see a reason why it
> > > > wouldn't be
> > > > valid to do it from an in kernel path as we do for PULL-UPS and
> > > > PULL-
> > > > DOWNS 
> > > > 
> > > 
> > > > > If you are looking for the place where FLAG_BIAS_DISABLE is
> > > > > set
> > > > > it is
> > > > > in
> > > > > gpio_v2_line_config_flags_to_desc_flags() in gpiolib-cdev.c.
> > > > > 
> > > > > Referring to gpio_set_bias(), the only place in gpiolib the
> > > > > FLAG_BIAS_DISABLE is used, if neither FLAG_PULL_UP,
> > > > > FLAG_PULL_DOWN,
> > > > > nor FLAG_BIAS_DISABLE are set then the bias configuration
> > > > > remains
> > > > > unchanged (the don't care case) - no change is passed to the
> > > > > driver.
> > > > > Otherwise the corresponding PIN_CONFIG_BIAS flag is passed to
> > > > > the
> > > > > driver.
> > > > > 
> > > > 
> > > > Exactly, but note FLAG_BIAS_DISABLE can only be set from
> > > > userspace
> > > > at
> > > > this point (IIUTC). If everyone agrees that should be case, so
> > > > be
> > > > it.
> > > > But as I said, I just don't see why it's wrong to do it within
> > > > the
> > > > kernel.
> > > > 
> > > 
> > > Believe it or not gpiolib-cdev is part of the kernel, not
> > > userspace -
> > > it
> > > just provides an interface to userspace.
> > > 
> > 
> > Yes, I do know that. But don't you still need a userspace process
> > to
> > open the cdev and do the ioctl()?
> > 
> 
> Only if you want to drive the cdev interface, so not in this case.
> You would not use cdev, you would use gpiolib directly.
> 

That's what I'm trying to do :). Without having to change gpiod
consumers to have to explicitly set this flag.

> > > Bias can be disabled by calling gpiod_direction_input() or
> > > gpiod_direction_output() after setting the FLAG_BIAS_DISABLE, as
> > > gpiolib-cdev does.
> > > 
> > > Does that work for you?
> > > 
> > 
> > I'm not seeing how would this work... We would need to make gpiod
> > consumers having to do this. Something like:
> > 
> > 
> > desc = giod_get();
> > set_bit(FLAG_BIAS_DISABLE, &desc->flags);
> > set_direction...
> > 
> > 
> 
> In a nutshell.
> 
> If that solves your immediate problem then you need to decide what
> problem your patch is trying to address.
> 
> 

So my patch is trying to solve exactly this case because (IMO), it does
not make sense for consumers drivers to have to do the above code.
Moreover, they would need some custom firmware property (eg:
devicetree) for the cases where we want to disable BIAS since we cannot
just assume we want to do it.

Well, maybe we can just assume FLAG_BIAS_DISABLE in gpiolib (when
trying to get the gpiod) if no PULL is specified. However, I do have
some concerns with it (see my conversation with Andy in the cover).

- Nuno Sá
Andy Shevchenko July 14, 2022, 3:08 p.m. UTC | #8
On Thu, Jul 14, 2022 at 03:02:08PM +0200, Nuno Sá wrote:
> On Thu, 2022-07-14 at 20:00 +0800, Kent Gibson wrote:
> > On Thu, Jul 14, 2022 at 10:47:27AM +0200, Nuno Sá wrote:

...

> > If that solves your immediate problem then you need to decide what
> > problem your patch is trying to address.
> 
> So my patch is trying to solve exactly this case because (IMO), it does
> not make sense for consumers drivers to have to do the above code.
> Moreover, they would need some custom firmware property (eg:
> devicetree) for the cases where we want to disable BIAS since we cannot
> just assume we want to do it.

Why? This is the main question. Why do you need that _in kernel_ API.

> Well, maybe we can just assume FLAG_BIAS_DISABLE in gpiolib (when
> trying to get the gpiod) if no PULL is specified. However, I do have
> some concerns with it (see my conversation with Andy in the cover).

It's AS IS if you trust firmware.
Nuno Sá July 14, 2022, 3:47 p.m. UTC | #9
On Thu, 2022-07-14 at 18:08 +0300, Andy Shevchenko wrote:
> On Thu, Jul 14, 2022 at 03:02:08PM +0200, Nuno Sá wrote:
> > On Thu, 2022-07-14 at 20:00 +0800, Kent Gibson wrote:
> > > On Thu, Jul 14, 2022 at 10:47:27AM +0200, Nuno Sá wrote:
> 
> ...
> 
> > > If that solves your immediate problem then you need to decide
> > > what
> > > problem your patch is trying to address.
> > 
> > So my patch is trying to solve exactly this case because (IMO), it
> > does
> > not make sense for consumers drivers to have to do the above code.
> > Moreover, they would need some custom firmware property (eg:
> > devicetree) for the cases where we want to disable BIAS since we
> > cannot
> > just assume we want to do it.
> 
> Why? This is the main question. Why do you need that _in kernel_ API.
> 
> > Well, maybe we can just assume FLAG_BIAS_DISABLE in gpiolib (when
> > trying to get the gpiod) if no PULL is specified. However, I do
> > have
> > some concerns with it (see my conversation with Andy in the cover).
> 
> It's AS IS if you trust firmware.
> 

In my use case, there's no firmware controlling the pin... The input
driver (which exposes the gpichip) directly controls the pins and I
want to have a way to tell it (from firmware) to disable the BIAS if
users want to do so (by default it's pull-up)...

- Nuno Sá
Linus Walleij July 18, 2022, 10:44 a.m. UTC | #10
On Wed, Jul 13, 2022 at 7:37 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> On Wed, Jul 13, 2022 at 03:14:18PM +0200, Nuno Sá wrote:
> > This change prepares the gpio core to look at firmware flags and set
> > 'FLAG_BIAS_DISABLE' if necessary. It works in similar way to
> > 'GPIO_PULL_DOWN' and 'GPIO_PULL_UP'.
>
> ...
>
> >       GPIO_PULL_UP                    = (1 << 4),
> >       GPIO_PULL_DOWN                  = (1 << 5),
> > +     GPIO_PULL_DISABLE               = (1 << 6),
>
> To me it seems superfluous. You have already two flags:
> PUp
> PDown
> When none is set --> Pdisable

What happens in the pin control case for some drivers at least is that
the machine
comes up with some pull up/downs enabled (by power-on default or from
the boot loader), and some systems need to explicitly disable these
pulls.

In these (device tree) cases they set bias-disable; in the device tree, and
the driver will actively disable any pull up/down.

OK this is maybe not the most elegant system engineering. But some of
those users are hobbyists and cannot affect what the ASIC or firmware
is doing, because vendors are not really listening.

Another semantic reason is that pins can also be set to bias-high-impedance;
which is what "some people" would assume is the default if you disable
both pull up and pull down. (Yeah ... semantics...)

Device tree also has bias-pull-pin-default; to make things more complicated.
This should *really* leave it at power-on default. Explicitly.

I think for Nuno's usecase (using a random pin from userspace) the state
of biasing cannot be assumed, the driver will not change bias to
disabled just because neither pull up or down is specified, so the driver
needs an explicit kick saying "disable any bias".

Yours,
Linus Walleij
diff mbox series

Patch

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 9535f48e18d1..0692ec84d3b0 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -3945,9 +3945,11 @@  int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
 	if (lflags & GPIO_OPEN_SOURCE)
 		set_bit(FLAG_OPEN_SOURCE, &desc->flags);
 
-	if ((lflags & GPIO_PULL_UP) && (lflags & GPIO_PULL_DOWN)) {
+	if (((lflags & GPIO_PULL_UP) && (lflags & GPIO_PULL_DOWN)) ||
+	    ((lflags & GPIO_PULL_UP) && (lflags & GPIO_PULL_DISABLE)) ||
+	    ((lflags & GPIO_PULL_DOWN) && (lflags & GPIO_PULL_DISABLE))) {
 		gpiod_err(desc,
-			  "both pull-up and pull-down enabled, invalid configuration\n");
+			  "multiple pull-up, pull-down or pull-disable enabled, invalid configuration\n");
 		return -EINVAL;
 	}
 
@@ -3955,6 +3957,8 @@  int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
 		set_bit(FLAG_PULL_UP, &desc->flags);
 	else if (lflags & GPIO_PULL_DOWN)
 		set_bit(FLAG_PULL_DOWN, &desc->flags);
+	else if (lflags & GPIO_PULL_DISABLE)
+		set_bit(FLAG_BIAS_DISABLE, &desc->flags);
 
 	ret = gpiod_set_transitory(desc, (lflags & GPIO_TRANSITORY));
 	if (ret < 0)
diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h
index 4d55da28e664..0b619eb7ae83 100644
--- a/include/linux/gpio/machine.h
+++ b/include/linux/gpio/machine.h
@@ -14,6 +14,7 @@  enum gpio_lookup_flags {
 	GPIO_TRANSITORY			= (1 << 3),
 	GPIO_PULL_UP			= (1 << 4),
 	GPIO_PULL_DOWN			= (1 << 5),
+	GPIO_PULL_DISABLE		= (1 << 6),
 
 	GPIO_LOOKUP_FLAGS_DEFAULT	= GPIO_ACTIVE_HIGH | GPIO_PERSISTENT,
 };