| 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 | |