diff options
| author | Martin Aberer <martin.aberer@bachmann.info> | 2026-03-24 17:05:56 +0300 |
|---|---|---|
| committer | Andi Shyti <andi.shyti@kernel.org> | 2026-03-27 16:53:25 +0300 |
| commit | 8461f5e3887404b19ba073fd1cc92e2f8f73185b (patch) | |
| tree | 826f66457e5c4f2d4beb0a913d89bb97b832e16a | |
| parent | 3762e535f2c9b31716a982d9fdd5c51d5ec7aa42 (diff) | |
| download | linux-8461f5e3887404b19ba073fd1cc92e2f8f73185b.tar.xz | |
i2c: ocores: Use read_poll_timeout_atomic to avoid false poll timeouts
Replace the manual polling loop in ocores_wait() with the kernel helper
read_poll_timeout_atomic(). This simplifies the code and ensures robust
timeout handling.
In particular, the helper guarantees a condition check after the
delay, even if the delay exceeds the timeout, avoiding spurious
timeout errors under load or preemption.
Signed-off-by: Martin Aberer <martin.aberer@bachmann.info>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://lore.kernel.org/r/20260324140556.2249039-1-martin.aberer@bachmann.info
| -rw-r--r-- | drivers/i2c/busses/i2c-ocores.c | 24 |
1 files changed, 9 insertions, 15 deletions
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 0f67e57cdeff..df6ebf32d6e8 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -24,6 +24,7 @@ #include <linux/io.h> #include <linux/log2.h> #include <linux/spinlock.h> +#include <linux/iopoll.h> #include <linux/jiffies.h> /* @@ -258,7 +259,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_us: timeout in microseconds * * Timeout is necessary to avoid to stay here forever when the chip * does not answer correctly. @@ -267,21 +268,14 @@ static void ocores_process_timeout(struct ocores_i2c *i2c) */ static int ocores_wait(struct ocores_i2c *i2c, int reg, u8 mask, u8 val, - const unsigned long timeout) + unsigned long timeout_us) { - unsigned long j; + u8 status; - j = jiffies + timeout; - while (1) { - u8 status = oc_getreg(i2c, reg); - - if ((status & mask) == val) - break; - - if (time_after(jiffies, j)) - return -ETIMEDOUT; - } - return 0; + return read_poll_timeout_atomic(oc_getreg, status, + (status & mask) == val, + 0, timeout_us, false, + i2c, reg); } /** @@ -314,7 +308,7 @@ static int ocores_poll_wait(struct ocores_i2c *i2c) * 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, 1000); if (err) dev_warn(i2c->adap.dev.parent, "%s: STATUS timeout, bit 0x%x did not clear in 1ms\n", |
