From 80d40626cc76f65f2699573a95ecc90a31dcf50e Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Tue, 12 Feb 2019 11:06:47 -0800 Subject: i2c: tegra: update transfer timeout Tegra194 allows max of 64K bytes and Tegra186 and prior allows max of 4K bytes of transfer per packet. one sec timeout is not enough for transfers more than 10K bytes at STD bus rate. This patch updates I2C transfer timeout based on the transfer size and I2C bus rate to allow enough time during max transfer size at lower bus speed. Acked-by: Thierry Reding Reviewed-by: Dmitry Osipenko Signed-off-by: Sowjanya Komatineni Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-tegra.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 3b923411c9a7..cfecd81789c3 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -24,7 +24,6 @@ #include #include -#define TEGRA_I2C_TIMEOUT (msecs_to_jiffies(1000)) #define BYTES_PER_FIFO_WORD 4 #define I2C_CNFG 0x000 @@ -936,7 +935,7 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap) tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE); time_left = wait_for_completion_timeout(&i2c_dev->msg_complete, - TEGRA_I2C_TIMEOUT); + msecs_to_jiffies(50)); if (time_left == 0) { dev_err(i2c_dev->dev, "timed out for bus clear\n"); return -ETIMEDOUT; @@ -963,6 +962,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, u32 *buffer = NULL; int err = 0; bool dma; + u16 xfer_time = 100; tegra_i2c_flush_fifos(i2c_dev); @@ -982,6 +982,12 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, i2c_dev->dma_buf; tegra_i2c_config_fifo_trig(i2c_dev, xfer_size); dma = i2c_dev->is_curr_dma_xfer; + /* + * Transfer time in mSec = Total bits / transfer rate + * Total bits = 9 bits per byte (including ACK bit) + Start & stop bits + */ + xfer_time += DIV_ROUND_CLOSEST(((xfer_size * 9) + 2) * MSEC_PER_SEC, + i2c_dev->bus_clk_rate); spin_lock_irqsave(&i2c_dev->xfer_lock, flags); int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST; @@ -1085,7 +1091,7 @@ unlock: time_left = wait_for_completion_timeout( &i2c_dev->dma_complete, - TEGRA_I2C_TIMEOUT); + msecs_to_jiffies(xfer_time)); if (time_left == 0) { dev_err(i2c_dev->dev, "DMA transfer timeout\n"); dmaengine_terminate_sync(i2c_dev->msg_read ? @@ -1111,7 +1117,7 @@ unlock: } time_left = wait_for_completion_timeout(&i2c_dev->msg_complete, - TEGRA_I2C_TIMEOUT); + msecs_to_jiffies(xfer_time)); tegra_i2c_mask_irq(i2c_dev, int_mask); if (time_left == 0) { @@ -1390,6 +1396,7 @@ static int tegra_i2c_probe(struct platform_device *pdev) i2c_dev->div_clk = div_clk; i2c_dev->adapter.algo = &tegra_i2c_algo; i2c_dev->adapter.retries = 1; + i2c_dev->adapter.timeout = 6 * HZ; i2c_dev->irq = irq; i2c_dev->cont_id = pdev->id; i2c_dev->dev = &pdev->dev; -- cgit v1.2.3