Re: [RFC v2 0/2] gpio: Support for shared GPIO lines on boards

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 01/11/2019 15.46, Rob Herring wrote:
> On Thu, Oct 31, 2019 at 3:00 AM Peter Ujfalusi <peter.ujfalusi@xxxxxx> wrote:
>>
>>
>>
>> On 30/10/2019 20.49, Rob Herring wrote:
>>> On Wed, Oct 30, 2019 at 9:30 AM Peter Ujfalusi <peter.ujfalusi@xxxxxx> wrote:
>>>>
>>>>
>>>>
>>>> On 30/10/2019 16.17, Mark Brown wrote:
>>>>> On Wed, Oct 30, 2019 at 03:32:09PM +0200, Peter Ujfalusi wrote:
>>>>>> On 30/10/2019 15.12, Rob Herring wrote:
>>>>>
>>>>>>> Why can't we just add a shared flag like we have for interrupts?
>>>>>>> Effectively, we have that for resets too, it's just hardcoded in the
>>>>>>> the drivers.
>>>>>
>>>>>> This would be kind of the same thing what the
>>>>>> GPIOD_FLAGS_BIT_NONEXCLUSIVE does, which was a quick workaround for
>>>>>> fixed-regulators afaik.
>>>>>
>>>>> The theory with that was that any usage of this would need the
>>>>> higher level code using the GPIO to cooperate so they didn't step
>>>>> on each other's toes so the GPIO code should just punt to it.
>>>>
>>>> But from the client driver point of view a GPIO is still GPIO and if the
>>>> components are unrelated then it is hard to patch things together from
>>>> the top.
>>>
>>> You can't escape a driver being aware. If a driver depends on that
>>> GPIO to actually be set to states the driver says, then it can't be
>>> guaranteed to work. For example, maybe the driver assumes the device
>>> is in reset state after toggling reset and doesn't work if not in
>>> reset state. The driver has to be aware no matter what you do in DT.
>>
>> That's true for some device, but it is also true that some can not
>> tolerate being reset without them knowing it.
> 
> You mean a reset when the driver is not loaded would not work? How
> could that ever work?

No, what I mean is that one device is reset because the driver for the
other device toggles the GPIO line.

If one driver toggles the GPIO line directly then the GPIO line is going
to be toggled for all the devices the GPIO line is connected to.

> I don't think you can have any reset control in
> the drivers in that case.

The device needs the RST line to be high, otherwise it is not
accessible. If it does not have reset control how can we make sure that
the GPIO line is in correct state?

gpio-hog does not work all the time because we can not trust probe order
and w/o gpio binding on the user deferred probing is not possible.
If for some reason the gpio controller is probed after the drivers
depending on the reset/enable GPIO then there's not much we can do.

>> If all users of the shared GPIO have full control over it then they can
>> just toggle it whatever way they want. How would a regulator, codec,
>> amplifier would negotiate on what to do with the shared GPIO?
>>
>> Another not uncommon setup is when the two components needs different level:
>> C1: ENABLE is high active
>> C2: RESET is high active
>>
>> To enable C1, the GPIO should be high. To enable C2 the GPIO must be low.
>> In the board one of the branch of the shared GPIO needs (and have) a
>> logic inverter.
>>
>> If they both control the same GPIO then they must have requested it with
>> different GPIO_ACTIVE_ since the drivers are written according to chip
>> spec, so C1 sets the GPIO to 1, C2 sets it to 0, the inversion for one
>> of them must happen in gpio core, right?
> 
> No, drivers are written to set the state to active/inactive.

I think the drivers are written in a way to follow what their datasheets
are tells. If it say that the GPIO line must be high to enable the
device then they gpiod_set_value(1), if the line must be low to enable
them then they will gpiod_set_value(0).

> The DT GPIO_ACTIVE_ flags can depend on an inverter being present (BTW, there
> was a recent attempt to do an inverter binding).

Yes.
If the line is inverted on the board, than the DT GPIO_ACTIVE_LOW will
invert it to the correct level.

We have two off the shelf components, C1 and C2. They have a driver
written based on the datasheets.
C1 needs HIGH (LOW reset/disable)
 uses gpiod_set_value(1) to enable the device

C2 needs LOW (HIGH reset/disable)
 uses gpiod_set_value(0) to enable the device

When they are connected to a dedicated GPIO the DT binding has
GPIO_ACTIVE_HIGH since when the GPIO is set to 1 it goes HIGH, right?

If two device is connected to one GPIO one of them needs an inverter on
the GPIO line after it is split into two, let say C2 got inverted line:
C1 tells in DT that the line is not inverted: GPIO_ACTIVE_HOGH
C2 tells in DT that the line is inverted: GPIO_ACTIVE_LOW

GPIO HIGH -> D1 is enabled
	  -> !HIGH -> LOW -> D2 is enabled

If both would request the same physical GPIO then how would this work? A
single GPIO can not be handled in inverted and non inverted way at the
same time.

But this is just a side effect that this would be easy to handle with
this DT binding and driver.
After all, it will describe the GPIO line split.

>> It should be possible to add pass-through mode for gpio-shared so that
>> all requests would propagate to the root GPIO if that's what needed for
>> some setups.
>>
>> That way the gpio-shared would nicely handle the GPIO inversions, would
>> be able to handle cases to avoid unwanted reset/enable of components or
>> allow components to be ninja-reset.
> 
> What does ninja-reset mean?

Ninjas attack from ambush ;)
The device is reset w/o it's driver being aware that it ever happened as
other driver toggled the shared GPIO line.

>> I think it would be possible to add gpiod_is_shared(struct gpio_desc
>> *desc) so users can check if the GPIO is shared - it would only return
>> true if the gpio-shared is not in pass-through mode so they can know
>> that the state they see on their gpio desc is not necessary matching
>> with reality.
>> Probably another gpiod_shared_get_root_value() to fetch the root's state?
>>
>> I intentionally not returning that in the driver as clients might skip a
>> gpio_set_value() seeing that the GPIO line is already in a state they
>> would want it, but that would not register their needs for the level.
>>
>> - Péter
>>
>> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
>> Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux