| From 4a34b9bf5f6f3f3ed910863fd1b4741a62864d4b Mon Sep 17 00:00:00 2001 |
| From: Tyrone Ting <kfting@nuvoton.com> |
| Date: Thu, 19 Dec 2024 17:08:56 +0800 |
| Subject: [PATCH 3/6] i2c: npcm: Modify timeout evaluation mechanism |
| |
| The users want to connect a lot of masters on the same bus. |
| This timeout is used to determine the time it takes to take bus ownership. |
| The transactions are very long, so waiting 35ms is not enough. |
| |
| Increase the timeout and treat it as the total timeout, including retries. |
| The total timeout is 2 seconds now. |
| |
| The i2c core layer will have chances to retry to call the i2c driver |
| transfer function if the i2c driver reports that the bus is busy and |
| returns -EAGAIN. |
| |
| Upstream-Status: Accepted |
| Signed-off-by: Tyrone Ting <kfting@nuvoton.com> |
| Reviewed-by: Tali Perry <tali.perry1@gmail.com> |
| Link: https://lore.kernel.org/r/20241219090859.18722-2-kfting@nuvoton.com |
| Signed-off-by: Andi Shyti <andi.shyti@kernel.org> |
| --- |
| drivers/i2c/busses/i2c-npcm7xx.c | 24 +++++++++++++++--------- |
| 1 file changed, 15 insertions(+), 9 deletions(-) |
| |
| diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c |
| index 482a0074d448..c96a25d37c14 100644 |
| --- a/drivers/i2c/busses/i2c-npcm7xx.c |
| +++ b/drivers/i2c/busses/i2c-npcm7xx.c |
| @@ -2132,19 +2132,12 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, |
| } |
| } |
| |
| - /* |
| - * Adaptive TimeOut: estimated time in usec + 100% margin: |
| - * 2: double the timeout for clock stretching case |
| - * 9: bits per transaction (including the ack/nack) |
| - */ |
| - timeout_usec = (2 * 9 * USEC_PER_SEC / bus->bus_freq) * (2 + nread + nwrite); |
| - timeout = max_t(unsigned long, bus->adap.timeout, usecs_to_jiffies(timeout_usec)); |
| if (nwrite >= 32 * 1024 || nread >= 32 * 1024) { |
| dev_err(bus->dev, "i2c%d buffer too big\n", bus->num); |
| return -EINVAL; |
| } |
| |
| - time_left = jiffies + timeout + 1; |
| + time_left = jiffies + bus->adap.timeout / bus->adap.retries + 1; |
| do { |
| /* |
| * we must clear slave address immediately when the bus is not |
| @@ -2192,6 +2185,14 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, |
| if (npcm_i2c_master_start_xmit(bus, slave_addr, nwrite, nread, |
| write_data, read_data, read_PEC, |
| read_block)) { |
| + /* |
| + * Adaptive TimeOut: estimated time in usec + 100% margin: |
| + * 2: double the timeout for clock stretching case |
| + * 9: bits per transaction (including the ack/nack) |
| + */ |
| + timeout_usec = (2 * 9 * USEC_PER_SEC / bus->bus_freq) * (2 + nread + nwrite); |
| + timeout = max_t(unsigned long, bus->adap.timeout / bus->adap.retries, |
| + usecs_to_jiffies(timeout_usec)); |
| time_left = wait_for_completion_timeout(&bus->cmd_complete, |
| timeout); |
| |
| @@ -2317,7 +2318,12 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev) |
| adap = &bus->adap; |
| adap->owner = THIS_MODULE; |
| adap->retries = 3; |
| - adap->timeout = msecs_to_jiffies(35); |
| + /* |
| + * The users want to connect a lot of masters on the same bus. |
| + * This timeout is used to determine the time it takes to take bus ownership. |
| + * The transactions are very long, so waiting 35ms is not enough. |
| + */ |
| + adap->timeout = 2 * HZ; |
| adap->algo = &npcm_i2c_algo; |
| adap->quirks = &npcm_i2c_quirks; |
| adap->algo_data = bus; |
| -- |
| 2.48.1.502.g6dc24dfdaf-goog |
| |