diff mbox series

[RFC,1/2] dt-bindings: gpio: Document shared GPIO line usage

Message ID 20191120133409.9217-2-peter.ujfalusi@ti.com
State RFC, archived
Headers show
Series [RFC,1/2] dt-bindings: gpio: Document shared GPIO line usage | expand

Checks

Context Check Description
robh/checkpatch success

Commit Message

Peter Ujfalusi Nov. 20, 2019, 1:34 p.m. UTC
Boards might use the same GPIO line to control several external devices.
Add section to document on how a shared GPIO pin can be described.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 .../devicetree/bindings/gpio/gpio.txt         | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)

Comments

Linus Walleij Nov. 22, 2019, 12:10 p.m. UTC | #1
On Wed, Nov 20, 2019 at 2:34 PM Peter Ujfalusi <peter.ujfalusi@ti.com> wrote:

> Boards might use the same GPIO line to control several external devices.
> Add section to document on how a shared GPIO pin can be described.
>
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>

As I've stated earlier I think this information is surplus.
If two devices have a phandle to the same GPIO line
then it is by definition shared.

> +               line_a {
> +                       gpio-shared;

So this is unnecessary: if the same line is referenced
by phandle from two places it is shared, simple as that.
It is up to code in the operating system (like Linux) to
detect if they are shared in practice (both consumer
nodes are enabled) and then deal with the outcome.

> +                       gpios = <5 0>;
> +                       output-low;

This is overlapping with the use case to define initial
state values for GPIOs, something that has been
brought up repeatedly and I've collected links for
previous discussions several times.

I guess if need be I have to look them up again.

The DT maintainers don't like the hog syntax so
something else is desired for this.

> +                       refcounted-high;
(snip)
> +The shared GPIO line management strategy can be selected with either of the
> +following properties:
> +- refcounted-low: The line must be kept low as long as there is at least one
> +               request asking it to be low.
> +- refcounted-high: The line must be kept high as long as there is at least one
> +               request asking it to be high.

Is this really needed? Isn't it more appropriate to just define the
semantics such that as soon as some consumer requests the line
high it will be refcounted high, and as soon as it is requested
low by any consumer it will be refcounted low.

> +If neither of the refcounting strategy was selected then the shared GPIO is
> +handled as pass through. In this mode all user requests will be forwarded to the
> +shared GPIO pin without refcounting.

Why should this even be allowed? If we are defining a special semantic
for refcounted GPIOs (even defining a separate API in the Linux
OS, though it is beside the point) why do we have to have a fallback
to the old behaviour at all?

I think you can do this by just detecting multiple phandles to the
same GPIO and implicit refcounting for > 1 consumers.

I.e. no new bindings at all, maybe some patches explaining the
semantic effect of using the same GPIO from two consumer
nodes.

Yours,
Linus Walleij
Peter Ujfalusi Nov. 22, 2019, 1:36 p.m. UTC | #2
On 22/11/2019 14.10, Linus Walleij wrote:
> On Wed, Nov 20, 2019 at 2:34 PM Peter Ujfalusi <peter.ujfalusi@ti.com> wrote:
> 
>> Boards might use the same GPIO line to control several external devices.
>> Add section to document on how a shared GPIO pin can be described.
>>
>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> 
> As I've stated earlier I think this information is surplus.
> If two devices have a phandle to the same GPIO line
> then it is by definition shared.

Well, phandle + line number to be precise. There might be a way to grep
the whole DT and figure out if really we have multiple users for the
same line behind of the phandle.

> 
>> +               line_a {
>> +                       gpio-shared;
> 
> So this is unnecessary: if the same line is referenced
> by phandle from two places it is shared, simple as that.

phandle is pointing to the gpio controller, not to the line.

> It is up to code in the operating system (like Linux) to
> detect if they are shared in practice (both consumer
> nodes are enabled) and then deal with the outcome.

Ideally yes.

>> +                       gpios = <5 0>;
>> +                       output-low;
> 
> This is overlapping with the use case to define initial
> state values for GPIOs, something that has been
> brought up repeatedly and I've collected links for
> previous discussions several times.

I don't mind this to go away and the first set would configure the level.
Kept it here so I can reuse the gpio-hog code from gpiolib-of ;)

> I guess if need be I have to look them up again.
> 
> The DT maintainers don't like the hog syntax so
> something else is desired for this.

I see, so the gpio-hog might change?

>> +                       refcounted-high;
> (snip)
>> +The shared GPIO line management strategy can be selected with either of the
>> +following properties:
>> +- refcounted-low: The line must be kept low as long as there is at least one
>> +               request asking it to be low.
>> +- refcounted-high: The line must be kept high as long as there is at least one
>> +               request asking it to be high.
> 
> Is this really needed? Isn't it more appropriate to just define the
> semantics such that as soon as some consumer requests the line
> high it will be refcounted high, and as soon as it is requested
> low by any consumer it will be refcounted low.

Well. How do we decide which level is the one that should be preserved?

How would the core decide what to in a simplest case:
two device, they are the same part.
ENABLE pin which needs to be high to enable the device.
When the driver probes it asks for initial deasserted GPIO as the device
is not in active use.

We are refcouting low?

Then one device is enabled, it asks for assert for the line.

We are now refcounting high?

Then the other device is also enabled, it also asserts the line.

We are still refcounting high?

_one_ of the device is no longer in use, the driver asks for deassert.

We are switching to refcount low and set the line low?
That would break the other device as it still want the line high.

and no, we can not refcount for the asserted state as if the pin is
RESET and active low, then assert will disable the devices.

Now if you throw in a third device to the mix, the whole global
refcounting will be off even more.

Furthermore:
If you have two different devices one with ENABLE (low=reset,
high=enabled) the other with RESET (low=reset, high=enabled) pin and
they are described in DT correctly and the driver is written correctly
for assert/deassert, then this dummy shared implementation will just
fail as we are sharing the same gpio_desc between them, but they want to
use it with different GPIO_ACTIVE_* level.

>> +If neither of the refcounting strategy was selected then the shared GPIO is
>> +handled as pass through. In this mode all user requests will be forwarded to the
>> +shared GPIO pin without refcounting.
> 
> Why should this even be allowed? If we are defining a special semantic
> for refcounted GPIOs (even defining a separate API in the Linux
> OS, though it is beside the point) why do we have to have a fallback
> to the old behaviour at all?

I kept it because there were comments for the gpio-shared driver
indicating that in some cases pass-through shared line might be needed
for some setups.

> I think you can do this by just detecting multiple phandles to the
> same GPIO and implicit refcounting for > 1 consumers.

You mean that at every gpio request we would parse the DT to see if
there is another gpio binding pointing to the same gpio pin?
Or want to do a parse for all gpio pins during boot and mark the pins
which have multiple gpio binding pointing to them?

> I.e. no new bindings at all, maybe some patches explaining the
> semantic effect of using the same GPIO from two consumer
> nodes.

The level that needs to be preserved need to be communicated somehow imho.

If you plan to have separate API for this as I believe you do, then probably

struct gpio_refcount_desc *gpiod_refcounted_get(struct device *dev,
					const char *con_id,
					enum gpiod_flags flags,
					bool i_care_for_asserted_state);

If the device have ENABLE with active high, the driver would:
gpiod_refcounted_get(dev, "enable", GPIOD_OUT_DEASSERTED, true);

if it has RESET with active low, the driver would:
gpiod_refcounted_get(dev, "reset", GPIOD_OUT_ASSERTED, false);

if it is desired that the device would be placed in reset/power-down
when the driver probes.

Then the core would need to figure out what these actually mean at the end.

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
Linus Walleij Nov. 28, 2019, 10:06 a.m. UTC | #3
On Fri, Nov 22, 2019 at 2:36 PM Peter Ujfalusi <peter.ujfalusi@ti.com> wrote:
> On 22/11/2019 14.10, Linus Walleij wrote:
> > On Wed, Nov 20, 2019 at 2:34 PM Peter Ujfalusi <peter.ujfalusi@ti.com> wrote:
> >
> >> Boards might use the same GPIO line to control several external devices.
> >> Add section to document on how a shared GPIO pin can be described.
> >>
> >> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> >
> > As I've stated earlier I think this information is surplus.
> > If two devices have a phandle to the same GPIO line
> > then it is by definition shared.
>
> Well, phandle + line number to be precise.

This is what I mean when I say "phandle to the same GPIO line".
Like this:

foo-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;

If the phandle <&gpio0 5 *>; appear in some other
(non-disabled) node it has > 1 users.

> >> +               line_a {
> >> +                       gpio-shared;
> >
> > So this is unnecessary: if the same line is referenced
> > by phandle from two places it is shared, simple as that.
>
> phandle is pointing to the gpio controller, not to the line.

Cleared up above.

> >> +                       gpios = <5 0>;
> >> +                       output-low;
> >
> > This is overlapping with the use case to define initial
> > state values for GPIOs, something that has been
> > brought up repeatedly and I've collected links for
> > previous discussions several times.
>
> I don't mind this to go away and the first set would configure the level.
> Kept it here so I can reuse the gpio-hog code from gpiolib-of ;)

People have tried to reuse the hog code to set up
initial line levels as well, it failed because they could
not get the DT bindings through the door.

> > I guess if need be I have to look them up again.
> >
> > The DT maintainers don't like the hog syntax so
> > something else is desired for this.
>
> I see, so the gpio-hog might change?

They will not change since they are ABI, but their
use case will not be extended AFAICT.
Not my pick, I liked the hog syntax but we need
consensus.

> > (snip)
> >> +The shared GPIO line management strategy can be selected with either of the
> >> +following properties:
> >> +- refcounted-low: The line must be kept low as long as there is at least one
> >> +               request asking it to be low.
> >> +- refcounted-high: The line must be kept high as long as there is at least one
> >> +               request asking it to be high.
> >
> > Is this really needed? Isn't it more appropriate to just define the
> > semantics such that as soon as some consumer requests the line
> > high it will be refcounted high, and as soon as it is requested
> > low by any consumer it will be refcounted low.
>
> Well. How do we decide which level is the one that should be preserved?

First come first serve.

If there is any conflict amongst the consumers we are
screwed anyway so why try to establish where they should
agree if they don't agree?

> How would the core decide what to in a simplest case:
> two device, they are the same part.
> ENABLE pin which needs to be high to enable the device.
> When the driver probes it asks for initial deasserted GPIO as the device
> is not in active use.

This makes me think it should be a unique driver
with a unique compatible string, as it embodies
use cases.

It is too broad to just define
refcounted-high or refcounted-low, that is hiding the
real use case, so I would go for something like a
resource in the device tree that all other devices that
need it can take.

Like a reset controller, precisely:

reset: reset-controller {
    compatible = "reset-gpio";
    gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
    #reset-cells = <0>;
};

dev0 {
    resets = <&reset>;
};

dev1 {
    resets = <&reset>;
};

The ambition to use refcounted GPIOs to solve this
usecase is probably wrong, I would say try to go for a
GPIO-based reset controller instead.

The fact that some Linux drivers are already using explicit
GPIO's for their reset handling is maybe unfortunate,
they will simply have to grow code to deal with a reset
alternatively to GPIO, like first try to grab a reset
handle and if that doesn't fall back to use a GPIO.

I would say don't try to shoehorn this use case into the
gpio library but instead try to create a reset controller that
takes care of arbitrating the use of a single GPIO line.

Yours,
Linus Walleij
Peter Ujfalusi Dec. 2, 2019, 9:31 p.m. UTC | #4
On 28/11/2019 12.06, Linus Walleij wrote:
> On Fri, Nov 22, 2019 at 2:36 PM Peter Ujfalusi <peter.ujfalusi@ti.com> wrote:
>> On 22/11/2019 14.10, Linus Walleij wrote:
>>> On Wed, Nov 20, 2019 at 2:34 PM Peter Ujfalusi <peter.ujfalusi@ti.com> wrote:
>>>
>>>> Boards might use the same GPIO line to control several external devices.
>>>> Add section to document on how a shared GPIO pin can be described.
>>>>
>>>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
>>>
>>> As I've stated earlier I think this information is surplus.
>>> If two devices have a phandle to the same GPIO line
>>> then it is by definition shared.
>>
>> Well, phandle + line number to be precise.
> 
> This is what I mean when I say "phandle to the same GPIO line".
> Like this:
> 
> foo-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
> 
> If the phandle <&gpio0 5 *>; appear in some other
> (non-disabled) node it has > 1 users.

I thought so.
Not sure how to look up (and how expensive it is) to find the nodes
which contain any gpio(lib) binding pointing to the given line.

> 
>>>> +               line_a {
>>>> +                       gpio-shared;
>>>
>>> So this is unnecessary: if the same line is referenced
>>> by phandle from two places it is shared, simple as that.
>>
>> phandle is pointing to the gpio controller, not to the line.
> 
> Cleared up above.
> 
>>>> +                       gpios = <5 0>;
>>>> +                       output-low;
>>>
>>> This is overlapping with the use case to define initial
>>> state values for GPIOs, something that has been
>>> brought up repeatedly and I've collected links for
>>> previous discussions several times.
>>
>> I don't mind this to go away and the first set would configure the level.
>> Kept it here so I can reuse the gpio-hog code from gpiolib-of ;)
> 
> People have tried to reuse the hog code to set up
> initial line levels as well, it failed because they could
> not get the DT bindings through the door.

But we are happily using the gpio-hog to control board level muxes to
select functionality...

Initial level is a tricky one, for outputs there is a valid use case for
them for sure. If the GPIO is used to control LCD backlight for example.
You want the backlight to not flicker due to gpio state changes.

It depends on how it is configured when the kernel boots, do we have
users of the given GPIO.

Again, different issue.

>>> I guess if need be I have to look them up again.
>>>
>>> The DT maintainers don't like the hog syntax so
>>> something else is desired for this.
>>
>> I see, so the gpio-hog might change?
> 
> They will not change since they are ABI, but their
> use case will not be extended AFAICT.
> Not my pick, I liked the hog syntax but we need
> consensus.

OK.

>>> (snip)
>>>> +The shared GPIO line management strategy can be selected with either of the
>>>> +following properties:
>>>> +- refcounted-low: The line must be kept low as long as there is at least one
>>>> +               request asking it to be low.
>>>> +- refcounted-high: The line must be kept high as long as there is at least one
>>>> +               request asking it to be high.
>>>
>>> Is this really needed? Isn't it more appropriate to just define the
>>> semantics such that as soon as some consumer requests the line
>>> high it will be refcounted high, and as soon as it is requested
>>> low by any consumer it will be refcounted low.
>>
>> Well. How do we decide which level is the one that should be preserved?
> 
> First come first serve.
> 
> If there is any conflict amongst the consumers we are
> screwed anyway so why try to establish where they should
> agree if they don't agree?

They must agree on the (precious, must be preserved) level _on_ the GPIO
chip side.
It is another matter if one driver will power down it's device at probe,
the other would enable it.
This must not matter, both of them needs the same level to be enabled
and it might not be the level they will request first.

>> How would the core decide what to in a simplest case:
>> two device, they are the same part.
>> ENABLE pin which needs to be high to enable the device.
>> When the driver probes it asks for initial deasserted GPIO as the device
>> is not in active use.
> 
> This makes me think it should be a unique driver
> with a unique compatible string, as it embodies
> use cases.

Like the gpio-shared from the previous RFC ;)

> It is too broad to just define
> refcounted-high or refcounted-low, that is hiding the
> real use case, so I would go for something like a
> resource in the device tree that all other devices that
> need it can take.
> 
> Like a reset controller, precisely:
> 
> reset: reset-controller {
>     compatible = "reset-gpio";
>     gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
>     #reset-cells = <0>;
> };
> 
> dev0 {
>     resets = <&reset>;
> };
> 
> dev1 {
>     resets = <&reset>;
> };
> 
> The ambition to use refcounted GPIOs to solve this
> usecase is probably wrong, I would say try to go for a
> GPIO-based reset controller instead.

I did that. A bit more lines of code than the gpio-shared.
Only works if all clients are converted to reset controller, all must
use reset_control_get_shared()

But my biggest issue was that how would you put a resets/reset-names to
DT for a device where the gpio is used for enabling an output/input pin
and not to place the device or part of the device to reset.

Sure, one can say that something is in 'reset' when it is not enabled,
but do you put the LCD backlight to 'reset' when you turn it off?

Is your DC motor in 'reset' when it is not working?

GPIO stands for General Purpose Input/Output, one of the purpose is to
enable/disable things, reset things, turn on/off things or anything one
could use 3.3V (or more/less).

> The fact that some Linux drivers are already using explicit
> GPIO's for their reset handling is maybe unfortunate,
> they will simply have to grow code to deal with a reset
> alternatively to GPIO, like first try to grab a reset
> handle and if that doesn't fall back to use a GPIO.

Sure, it can be done, but when we hit a case when the reset framework is
not fitting for some devices use of the shared GPIO, then what we will do?

> I would say don't try to shoehorn this use case into the
> gpio library but instead try to create a reset controller that
> takes care of arbitrating the use of a single GPIO line.

It would certainly cover the use case I have.

How would it satisfy the regulator use case? We put the regulators to
'reset' when they are turned off / disabled?

> 
> Yours,
> Linus Walleij
> 

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
Rob Herring Dec. 3, 2019, 11:51 p.m. UTC | #5
On Thu, Nov 28, 2019 at 11:06:35AM +0100, Linus Walleij wrote:
> On Fri, Nov 22, 2019 at 2:36 PM Peter Ujfalusi <peter.ujfalusi@ti.com> wrote:
> > On 22/11/2019 14.10, Linus Walleij wrote:
> > > On Wed, Nov 20, 2019 at 2:34 PM Peter Ujfalusi <peter.ujfalusi@ti.com> wrote:
> > >
> > >> Boards might use the same GPIO line to control several external devices.
> > >> Add section to document on how a shared GPIO pin can be described.
> > >>
> > >> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> > >
> > > As I've stated earlier I think this information is surplus.
> > > If two devices have a phandle to the same GPIO line
> > > then it is by definition shared.
> >
> > Well, phandle + line number to be precise.
> 
> This is what I mean when I say "phandle to the same GPIO line".
> Like this:
> 
> foo-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
> 
> If the phandle <&gpio0 5 *>; appear in some other
> (non-disabled) node it has > 1 users.
> 
> > >> +               line_a {
> > >> +                       gpio-shared;
> > >
> > > So this is unnecessary: if the same line is referenced
> > > by phandle from two places it is shared, simple as that.
> >
> > phandle is pointing to the gpio controller, not to the line.
> 
> Cleared up above.
> 
> > >> +                       gpios = <5 0>;
> > >> +                       output-low;
> > >
> > > This is overlapping with the use case to define initial
> > > state values for GPIOs, something that has been
> > > brought up repeatedly and I've collected links for
> > > previous discussions several times.
> >
> > I don't mind this to go away and the first set would configure the level.
> > Kept it here so I can reuse the gpio-hog code from gpiolib-of ;)
> 
> People have tried to reuse the hog code to set up
> initial line levels as well, it failed because they could
> not get the DT bindings through the door.
> 
> > > I guess if need be I have to look them up again.
> > >
> > > The DT maintainers don't like the hog syntax so
> > > something else is desired for this.
> >
> > I see, so the gpio-hog might change?
> 
> They will not change since they are ABI, but their
> use case will not be extended AFAICT.
> Not my pick, I liked the hog syntax but we need
> consensus.
> 
> > > (snip)
> > >> +The shared GPIO line management strategy can be selected with either of the
> > >> +following properties:
> > >> +- refcounted-low: The line must be kept low as long as there is at least one
> > >> +               request asking it to be low.
> > >> +- refcounted-high: The line must be kept high as long as there is at least one
> > >> +               request asking it to be high.
> > >
> > > Is this really needed? Isn't it more appropriate to just define the
> > > semantics such that as soon as some consumer requests the line
> > > high it will be refcounted high, and as soon as it is requested
> > > low by any consumer it will be refcounted low.
> >
> > Well. How do we decide which level is the one that should be preserved?
> 
> First come first serve.
> 
> If there is any conflict amongst the consumers we are
> screwed anyway so why try to establish where they should
> agree if they don't agree?
> 
> > How would the core decide what to in a simplest case:
> > two device, they are the same part.
> > ENABLE pin which needs to be high to enable the device.
> > When the driver probes it asks for initial deasserted GPIO as the device
> > is not in active use.
> 
> This makes me think it should be a unique driver
> with a unique compatible string, as it embodies
> use cases.
> 
> It is too broad to just define
> refcounted-high or refcounted-low, that is hiding the
> real use case, so I would go for something like a
> resource in the device tree that all other devices that
> need it can take.

I have similar thoughts.

> Like a reset controller, precisely:
> 
> reset: reset-controller {
>     compatible = "reset-gpio";
>     gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
>     #reset-cells = <0>;
> };
> 
> dev0 {
>     resets = <&reset>;
> };
> 
> dev1 {
>     resets = <&reset>;
> };

> 
> The ambition to use refcounted GPIOs to solve this
> usecase is probably wrong, I would say try to go for a
> GPIO-based reset controller instead.

Yes, but I think we can have that AND use the existing binding.

> The fact that some Linux drivers are already using explicit
> GPIO's for their reset handling is maybe unfortunate,
> they will simply have to grow code to deal with a reset
> alternatively to GPIO, like first try to grab a reset
> handle and if that doesn't fall back to use a GPIO.

I think this could just be all handled within the reset subsystem given 
that we've been consistent in using 'reset-gpios' (GPIO regulators are 
similar, but we never had such consistency with GPIO names for 
regulators). We can implement a reset driver for the 'reset-gpios' 
property that deals with the sharing. Drivers to DT nodes doesn't have 
to be 1:1. It's convenient when they are, but that's encoding the OS's 
(current) driver structure into DT.

Rob
Linus Walleij Dec. 10, 2019, 11:54 p.m. UTC | #6
On Wed, Dec 4, 2019 at 12:51 AM Rob Herring <robh@kernel.org> wrote:
> On Thu, Nov 28, 2019 at 11:06:35AM +0100, Linus Walleij wrote:

> > The ambition to use refcounted GPIOs to solve this
> > usecase is probably wrong, I would say try to go for a
> > GPIO-based reset controller instead.
>
> Yes, but I think we can have that AND use the existing binding.
>
> > The fact that some Linux drivers are already using explicit
> > GPIO's for their reset handling is maybe unfortunate,
> > they will simply have to grow code to deal with a reset
> > alternatively to GPIO, like first try to grab a reset
> > handle and if that doesn't fall back to use a GPIO.
>
> I think this could just be all handled within the reset subsystem given
> that we've been consistent in using 'reset-gpios' (GPIO regulators are
> similar, but we never had such consistency with GPIO names for
> regulators). We can implement a reset driver for the 'reset-gpios'
> property that deals with the sharing. Drivers to DT nodes doesn't have
> to be 1:1. It's convenient when they are, but that's encoding the OS's
> (current) driver structure into DT.

This seems like a good approach if it can be made to work.
reset-gpios should have the right polarity flags (else drivers
and/or device trees need to be fixed...) so the driver can simply
scan over them and try to build a consensus on how to assert
or deassert a shared reset-gpios line.

It is also a natural placeholder for the connection to device
core that will inevitably need to happen the day the device
hierarchy needs to be torn up/down for a reset on some
random device.

Peter, will you have a go at it?

Yours,
Linus Walleij
Linus Walleij Dec. 11, 2019, 12:06 a.m. UTC | #7
On Mon, Dec 2, 2019 at 10:31 PM Peter Ujfalusi <peter.ujfalusi@ti.com> wrote:
> On 28/11/2019 12.06, Linus Walleij wrote:

> > The ambition to use refcounted GPIOs to solve this
> > usecase is probably wrong, I would say try to go for a
> > GPIO-based reset controller instead.
>
> I did that. A bit more lines of code than the gpio-shared.
> Only works if all clients are converted to reset controller, all must
> use reset_control_get_shared()

I don't think that's too much to ask, the usecase needs to
be expressed somewhere whether in code or DT properties.

> But my biggest issue was that how would you put a resets/reset-names to
> DT for a device where the gpio is used for enabling an output/input pin
> and not to place the device or part of the device to reset.

Rob suggest using GPIOs but represent them in the Linux kernel
as resets.

This would be a semantic effect of the line being named "reset-gpios"
as Rob pointed out. Name implies usage. We can formalize it
with DT YAML as well, these days, then it is impossible to get it
wrong, as long as the bindings are correct.

When you call the reset subsystem to create the reset handle
it can be instructed to look for a GPIO, possibly shared, and
this way replace the current explicit GPIO handling code
in the driver. It will just look as a reset no matter how many
other device or just this one is using it.

> Sure, one can say that something is in 'reset' when it is not enabled,
> but do you put the LCD backlight to 'reset' when you turn it off?
>
> Is your DC motor in 'reset' when it is not working?
>
> GPIO stands for General Purpose Input/Output, one of the purpose is to
> enable/disable things, reset things, turn on/off things or anything one
> could use 3.3V (or more/less).

Answered by explict interpretation of DT bindings
named "reset-gpios". Those are resets, nothing else.

> > The fact that some Linux drivers are already using explicit
> > GPIO's for their reset handling is maybe unfortunate,
> > they will simply have to grow code to deal with a reset
> > alternatively to GPIO, like first try to grab a reset
> > handle and if that doesn't fall back to use a GPIO.
>
> Sure, it can be done, but when we hit a case when the reset framework is
> not fitting for some devices use of the shared GPIO, then what we will do?

That can be said about literally anything we do in any
framework we design. Rough consensus and running code.
Bad paths will be taken sometimes, hopefully not too much.
We clean up the mess we create and refactor as we go
along, it is always optimistic design.

> How would it satisfy the regulator use case? We put the regulators to
> 'reset' when they are turned off / disabled?

We don't try to fix that now, if it's not broken don't fix it.
Let's try to fix the reset problem instead.

Yours,
Linus Walleij
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt
index a8895d339bfe..644e6513607c 100644
--- a/Documentation/devicetree/bindings/gpio/gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio.txt
@@ -228,6 +228,72 @@  Example of two SOC GPIO banks defined as gpio-controller nodes:
 		#gpio-cells = <2>;
 	};
 
+On boards one GPIO line might be connected to multiple devices as reset, enable
+or other control pins. In order to make it safer for this usage of a GPIO line
+one can describe the shared GPIO pin.
+
+Each shared GPIO pin definition is represented as a child node of the GPIO
+controller.
+
+Required properties:
+- gpio-shared:	A property specifying that this child node represents a shared
+		GPIO pin.
+- gpios:	Store the GPIO information (id, flags, ...) for each GPIO to
+		affect. Shall contain an integer multiple of the number of cells
+		specified in its parent node (GPIO controller node).
+Only one of the following properties scanned in the order shown below.
+This means that when multiple properties are present they will be searched
+in the order presented below and the first match is taken as the intended
+configuration.
+- output-low:	A property specifying to set the GPIO direction as output with
+		the value low initially.
+- output-high:	A property specifying to set the GPIO direction as output with
+		the value high initially.
+The shared GPIO line management strategy can be selected with either of the
+following properties:
+- refcounted-low: The line must be kept low as long as there is at least one
+		request asking it to be low.
+- refcounted-high: The line must be kept high as long as there is at least one
+		request asking it to be high.
+If neither of the refcounting strategy was selected then the shared GPIO is
+handled as pass through. In this mode all user requests will be forwarded to the
+shared GPIO pin without refcounting.
+
+Optional properties:
+- line-name:  The GPIO label name. If not present the node name is used.
+
+Example of shared GPIO use:
+
+	qe_pio_a: gpio-controller@1400 {
+		compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank";
+		reg = <0x1400 0x18>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		line_a {
+			gpio-shared;
+			gpios = <5 0>;
+			output-low;
+			refcounted-high;
+			line-name = "enable-for-devices";
+		};
+	};
+
+	device@0 {
+		compatible = "some,device";
+		enable-gpios = <&qe_pio_a 5 0>;
+	};
+
+	device@1 {
+		compatible = "some,device";
+		enable-gpios = <&qe_pio_a 5 0>;
+	};
+
+	component@0 {
+		compatible = "some,component";
+		select-gpios = <&qe_pio_a 5 0>;
+	};
+
 2.1) gpio- and pin-controller interaction
 -----------------------------------------