Re: [PATCH 2/4] reset: add GPIO-based reset controller

From: Krzysztof Kozlowski
Date: Tue Jan 09 2024 - 04:41:35 EST


On 05/01/2024 15:31, Philipp Zabel wrote:
>>>> Sorry, then I don't get what you refer to. The driver calls deassert
>>>> when it is safe for it to do it, so the driver *knows*. Now, you claim
>>>> that driver does not know that... core also does not know, so no one knows.
>>>
>>> Yes! That is the problem with this design. Someone has to coordinate the
>>> reset, and it can't be the driver. But the core also doesn't have enough
>>> information. So no one can do it.
>>
>> The point is that the driver coordinates.
>
> Currently the reset controller API supports two types of shared resets.
> I hope distinguishing the two types and illustrating them helps the
> discussion:
>
> 1) For devices that just require the reset to be deasserted while they
> are active, and don't care otherwise, there is the clk-like behavior
> described in [1].
>
> requested reset signal via reset_control_deassert/assert():
> device A: ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺
> device B: ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺
>
> actual reset signal to both devices:
> ⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺
>
> In this scenario, there should be no delays in the reset controller
> driver. reset_control_deassert() may return as soon as the physical
> reset signal is deasserted [2]. Any post-deassert delays required by
> the devices are handled in the device drivers, and they can be
> different for each device. The devices have to be able to cope with a
> (much) longer post-deassert delay than expected (e.g. device B in this
> case). It is assumed that the reset signal is initially asserted.
>
> The reset-gpio patchset supports this.

Yep! :)

>
> 2) The second type is for devices that require a single reset pulse for
> initialization, at any time before they become active. This is
> described in [3].
>
> requested reset signal via reset_control_reset/rearm():
> device A: ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
> device B: ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
>
> actual reset signal to both devices:
> ⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽/⎺⎺\⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽
>
> Here the reset controller needs to know the delay between assertion and
> deassertion - either baked into the hardware or as a delay call in the
> .reset callback.
>
> This is not supported by the reset-gpio patchset. It could be

Yep, as well.

> implemented via a delay property in the device tree that would have to
> be the same for all devices sharing the reset line, and by adding the

Or through dedicated node to which reset-gpio binds, just like in Sean's
code some years ago. Nothing stops achieving that, except of course
convincing Rob. The point is that although my design does not solve it,
it also does not prevent it in the future.

> .reset callback to the reset controller driver. The only issue is that
> the initial state of the reset line should be deasserted, and at
> reset_control_get() time, when the reset-gpio controller is
> instantiated, it is not yet known which type the driver will use.
>
> Sharing a reset line between devices of different type is not
> supported. Unfortunately, this will only fail at
> reset_control_deassert() / reset_control_reset() time when the second
> device tries to use the reset control in a different way than the
> first.
>
> [1] https://docs.kernel.org/driver-api/reset.html#assertion-and-deassertion
> [2] https://docs.kernel.org/driver-api/reset.html#c.reset_control_deassert
> [3] https://docs.kernel.org/driver-api/reset.html#triggering
>
>>> For example, say we want to share a reset GPIO between two devices. Each
>>> device has the following constraints:
>>>
>>> device post-assert delay post-deassert delay
>>> ====== ================= ===================
>>> A 500us 1ms
>>> B 1ms 300us
>>
>> And now imagine that these values are incompatible between them, so
>> using 1ms on device A is wrong - too long.
>>
>> This is just not doable. You invented some imaginary case to prove that
>> hardware is broken.
>>
>> Now, if we are back to realistic cases - use just the longest reset time.
>
> Right. This all only works if no device has an upper bound to the
> allowed delays on the shared reset line.

If device had an upper bound, it would be quite a conflicting design,
tricky to implement. I don't think we should target such case with
generic solution.

>
> I interpret the post-assert delay to be the desired length of the reset
> pulse between the rising edge and the falling edge in case 2) above,
> since in case 1) a post-assert delay is not useful.
>
> The post-deassert delays are not supposed to be handled by the reset
> controller drivers at all, except where they are needed to reach the
> deasserted state on the reset line. Reset drivers that do have post-
> deassert delays in the .deassert callback might be bending the rules a
> bit for convenience.


Best regards,
Krzysztof