mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/2] i2c: ocores: replace 1ms poll iteration timeout with total transfer timeout
@ 2025-10-07 12:09 Matthias Schiffer
  2025-10-07 12:09 ` [PATCH 2/2] i2c: ocores: respect adapter timeout in IRQ mode Matthias Schiffer
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Matthias Schiffer @ 2025-10-07 12:09 UTC (permalink / raw)
  To: Peter Korsgaard, Andrew Lunn, Andi Shyti
  Cc: linux-i2c, linux-kernel, linux, Matthias Schiffer

When a target makes use of clock stretching, a timeout of 1ms may not be
enough. One extreme example is the NXP PTN3460 eDP to LVDS bridge, which
takes ~320ms to send its ACK after a flash command has been
submitted.

Replace the per-iteration timeout of 1ms with limiting the total
transfer time to the timeout set in struct i2c_adapter (defaulting to
1s, configurable through the I2C_TIMEOUT ioctl). While we're at it, also
add a cpu_relax() to the busy poll loop.

Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
---
 drivers/i2c/busses/i2c-ocores.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 0f67e57cdeff6..1746c8821a149 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -258,7 +258,7 @@ static void ocores_process_timeout(struct ocores_i2c *i2c)
  * @reg: register to query
  * @mask: bitmask to apply on register value
  * @val: expected result
- * @timeout: timeout in jiffies
+ * @timeout: absolute timeout in jiffies
  *
  * Timeout is necessary to avoid to stay here forever when the chip
  * does not answer correctly.
@@ -269,17 +269,16 @@ static int ocores_wait(struct ocores_i2c *i2c,
 		       int reg, u8 mask, u8 val,
 		       const unsigned long timeout)
 {
-	unsigned long j;
-
-	j = jiffies + timeout;
 	while (1) {
 		u8 status = oc_getreg(i2c, reg);
 
 		if ((status & mask) == val)
 			break;
 
-		if (time_after(jiffies, j))
+		if (time_after(jiffies, timeout))
 			return -ETIMEDOUT;
+
+		cpu_relax();
 	}
 	return 0;
 }
@@ -287,12 +286,13 @@ static int ocores_wait(struct ocores_i2c *i2c,
 /**
  * ocores_poll_wait() - Wait until is possible to process some data
  * @i2c: ocores I2C device instance
+ * @timeout: absolute timeout in jiffies
  *
  * Used when the device is in polling mode (interrupts disabled).
  *
  * Return: 0 on success, -ETIMEDOUT on timeout
  */
-static int ocores_poll_wait(struct ocores_i2c *i2c)
+static int ocores_poll_wait(struct ocores_i2c *i2c, unsigned long timeout)
 {
 	u8 mask;
 	int err;
@@ -310,15 +310,11 @@ static int ocores_poll_wait(struct ocores_i2c *i2c)
 		udelay((8 * 1000) / i2c->bus_clock_khz);
 	}
 
-	/*
-	 * once we are here we expect to get the expected result immediately
-	 * so if after 1ms we timeout then something is broken.
-	 */
-	err = ocores_wait(i2c, OCI2C_STATUS, mask, 0, msecs_to_jiffies(1));
+	err = ocores_wait(i2c, OCI2C_STATUS, mask, 0, timeout);
 	if (err)
-		dev_warn(i2c->adap.dev.parent,
-			 "%s: STATUS timeout, bit 0x%x did not clear in 1ms\n",
-			 __func__, mask);
+		dev_dbg(i2c->adap.dev.parent,
+			"%s: STATUS timeout, bit 0x%x did not clear\n",
+			__func__, mask);
 	return err;
 }
 
@@ -336,11 +332,12 @@ static int ocores_poll_wait(struct ocores_i2c *i2c)
  */
 static int ocores_process_polling(struct ocores_i2c *i2c)
 {
+	unsigned long timeout = jiffies + i2c->adap.timeout;
 	irqreturn_t ret;
 	int err = 0;
 
 	while (1) {
-		err = ocores_poll_wait(i2c);
+		err = ocores_poll_wait(i2c, timeout);
 		if (err)
 			break; /* timeout */
 
-- 
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
https://www.tq-group.com/


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-10-09 22:25 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-10-07 12:09 [PATCH 1/2] i2c: ocores: replace 1ms poll iteration timeout with total transfer timeout Matthias Schiffer
2025-10-07 12:09 ` [PATCH 2/2] i2c: ocores: respect adapter timeout in IRQ mode Matthias Schiffer
2025-10-07 14:32   ` Peter Korsgaard
2025-10-07 12:34 ` [PATCH 1/2] i2c: ocores: replace 1ms poll iteration timeout with total transfer timeout Andrew Lunn
2025-10-07 14:06   ` Matthias Schiffer
2025-10-07 14:20     ` Andrew Lunn
2025-10-07 14:41       ` Matthias Schiffer
2025-10-07 14:50         ` Andrew Lunn
2025-10-09 22:25 ` Andi Shyti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®