diff mbox series

[09/13] i2c: nomadik: fetch timeout-usecs property from devicetree

Message ID 20240215-mbly-i2c-v1-9-19a336e91dca@bootlin.com
State New
Headers show
Series [01/13] dt-bindings: i2c: nomadik: add timeout-usecs property bindings | expand

Commit Message

Théo Lebrun Feb. 15, 2024, 4:52 p.m. UTC
Allow overriding the default timeout value (200ms) from devicetree,
using the timeout-usecs property.

The i2c_adapter->timeout field is an unaccurate jiffies amount;
i2c-nomadik uses hrtimers for timeouts below one jiffy.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
 drivers/i2c/busses/i2c-nomadik.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Comments

Linus Walleij Feb. 19, 2024, 2:22 p.m. UTC | #1
On Thu, Feb 15, 2024 at 5:52 PM Théo Lebrun <theo.lebrun@bootlin.com> wrote:

> Allow overriding the default timeout value (200ms) from devicetree,
> using the timeout-usecs property.
>
> The i2c_adapter->timeout field is an unaccurate jiffies amount;
> i2c-nomadik uses hrtimers for timeouts below one jiffy.
>
> Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>

Once we agree on the binding name:

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij
Wolfram Sang Feb. 27, 2024, 12:14 p.m. UTC | #2
> +	/* Slave response timeout */
> +	if (!of_property_read_u32(np, "timeout-usecs", &timeout_usecs))
> +		priv->timeout_usecs = timeout_usecs;
> +	else
> +		priv->timeout_usecs = 200 * USEC_PER_MSEC;

I could imagine to add 'transfer_timeout_us' to struct i2c_timings.
Then, you could use 'i2c_parse_fw_timings' to obtain the value. What
values/value range do you use here? I can't find them in the DTS
additions.
Théo Lebrun Feb. 27, 2024, 1:38 p.m. UTC | #3
Hello,

On Tue Feb 27, 2024 at 1:14 PM CET, Wolfram Sang wrote:
> > +	/* Slave response timeout */
> > +	if (!of_property_read_u32(np, "timeout-usecs", &timeout_usecs))
> > +		priv->timeout_usecs = timeout_usecs;
> > +	else
> > +		priv->timeout_usecs = 200 * USEC_PER_MSEC;
>
> I could imagine to add 'transfer_timeout_us' to struct i2c_timings.
> Then, you could use 'i2c_parse_fw_timings' to obtain the value. What
> values/value range do you use here? I can't find them in the DTS
> additions.

That sounds good. I have not used this prop in the DTS as it does not
make much sense for an eval board. The target is production boards.

An order of magnitude is a few transfers every 15ms. It means a timeout
of 15ms divided by "a few". I don't have more precise values, but I
could if you consider it useful.

I've done some testing at 50~100µs timeouts and it works as expected. At
those values timerslack is important to consider (default of 50µs).
This is at 400kHz clock frequency. Keep in mind the controllers support
up to 3.4MHz (not yet upstreamed) so timeouts could in theory go
lower if required by the usecase.

My upcoming question is how to move forward on this series. I can do the
patch to i2c_parse_fw_timings() in the next revision. That way it gets
added alongside the first user of this feature. Would it work for you?

Thanks,

--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Wolfram Sang Feb. 28, 2024, 10:49 a.m. UTC | #4
Hi Théo,

> That sounds good. I have not used this prop in the DTS as it does not
> make much sense for an eval board. The target is production boards.

...

> My upcoming question is how to move forward on this series. I can do the
> patch to i2c_parse_fw_timings() in the next revision. That way it gets
> added alongside the first user of this feature. Would it work for you?

Hmmm, to be honest I have a bit of an issue with the 'no user' problem.
There is a driver which uses this feature, okay. But there is no
upstream hardware which uses this driver with this new feature. This
makes maintaining harder ("Who uses this feature?" - "Someone" - "How do
they use it? Can we modify it?" - "Dunno").

Kind regards,

   Wolfram
Théo Lebrun Feb. 28, 2024, 1:39 p.m. UTC | #5
Hello Wolfram,

On Wed Feb 28, 2024 at 11:49 AM CET, Wolfram Sang wrote:
> > That sounds good. I have not used this prop in the DTS as it does not
> > make much sense for an eval board. The target is production boards.
>
> ...
>
> > My upcoming question is how to move forward on this series. I can do the
> > patch to i2c_parse_fw_timings() in the next revision. That way it gets
> > added alongside the first user of this feature. Would it work for you?
>
> Hmmm, to be honest I have a bit of an issue with the 'no user' problem.
> There is a driver which uses this feature, okay. But there is no
> upstream hardware which uses this driver with this new feature. This
> makes maintaining harder ("Who uses this feature?" - "Someone" - "How do
> they use it? Can we modify it?" - "Dunno").

The alternative is that I keep going with a new revision of i2c-nomadik
that manually parses the prop. It'll be refactored if/when the I2C core
provides a better way to access the value. Is that OK?

Thanks,

--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Wolfram Sang Feb. 29, 2024, 9:25 a.m. UTC | #6
> The alternative is that I keep going with a new revision of i2c-nomadik
> that manually parses the prop. It'll be refactored if/when the I2C core
> provides a better way to access the value. Is that OK?

That wouldn't have helped because there is still no user in-kernel of
that property, i.e. no DTS file with that property. But I just realized
that I need to convert i2c-mpc to avoid a deprecated binding, so we have
a user there. Lucky you ;)

I'll try to get the series done today.
diff mbox series

Patch

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index afd54999bbbb..23e12c570457 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -964,6 +964,8 @@  static const struct i2c_algorithm nmk_i2c_algo = {
 static void nmk_i2c_of_probe(struct device_node *np,
 			     struct nmk_i2c_dev *priv)
 {
+	u32 timeout_usecs;
+
 	/* Default to 100 kHz if no frequency is given in the node */
 	if (of_property_read_u32(np, "clock-frequency", &priv->clk_freq))
 		priv->clk_freq = I2C_MAX_STANDARD_MODE_FREQ;
@@ -975,7 +977,12 @@  static void nmk_i2c_of_probe(struct device_node *np,
 		priv->sm = I2C_FREQ_MODE_FAST;
 	priv->tft = 1; /* Tx FIFO threshold */
 	priv->rft = 8; /* Rx FIFO threshold */
-	priv->timeout_usecs = 200 * USEC_PER_MSEC; /* Slave response timeout */
+
+	/* Slave response timeout */
+	if (!of_property_read_u32(np, "timeout-usecs", &timeout_usecs))
+		priv->timeout_usecs = timeout_usecs;
+	else
+		priv->timeout_usecs = 200 * USEC_PER_MSEC;
 }
 
 static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)