aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorAbhishek Sahu <absahu@codeaurora.org>2018-03-12 18:44:58 +0530
committerWolfram Sang <wsa@the-dreams.de>2018-03-24 13:20:20 +0100
commitecb6e1e5f4352055a5761b945a833a925d51bf8d (patch)
tree2756f6072ba0e8c76e47dce06bf9077abfa66dbe /drivers/i2c
parenti2c: qup: use the complete transfer length to choose DMA mode (diff)
downloadlinux-dev-ecb6e1e5f4352055a5761b945a833a925d51bf8d.tar.xz
linux-dev-ecb6e1e5f4352055a5761b945a833a925d51bf8d.zip
i2c: qup: change completion timeout according to transfer length
Currently the completion timeout is being taken according to maximum transfer length which is too high if SCL is operating in high frequency. This patch calculates timeout on the basis of one-byte transfer time and uses the same for completion timeout. Signed-off-by: Abhishek Sahu <absahu@codeaurora.org> Reviewed-by: Andy Gross <andy.gross@linaro.org> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-qup.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index bf1b7eec8a4c..13c751e2dd9a 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -121,8 +121,12 @@
#define MX_TX_RX_LEN SZ_64K
#define MX_BLOCKS (MX_TX_RX_LEN / QUP_READ_LIMIT)
-/* Max timeout in ms for 32k bytes */
-#define TOUT_MAX 300
+/*
+ * Minimum transfer timeout for i2c transfers in seconds. It will be added on
+ * the top of maximum transfer time calculated from i2c bus speed to compensate
+ * the overheads.
+ */
+#define TOUT_MIN 2
/* Default values. Use these if FW query fails */
#define DEFAULT_CLK_FREQ 100000
@@ -163,6 +167,7 @@ struct qup_i2c_dev {
int in_blk_sz;
unsigned long one_byte_t;
+ unsigned long xfer_timeout;
struct qup_i2c_block blk;
struct i2c_msg *msg;
@@ -849,7 +854,7 @@ static int qup_i2c_bam_do_xfer(struct qup_i2c_dev *qup, struct i2c_msg *msg,
dma_async_issue_pending(qup->brx.dma);
}
- if (!wait_for_completion_timeout(&qup->xfer, TOUT_MAX * HZ)) {
+ if (!wait_for_completion_timeout(&qup->xfer, qup->xfer_timeout)) {
dev_err(qup->dev, "normal trans timed out\n");
ret = -ETIMEDOUT;
}
@@ -1605,6 +1610,8 @@ nodma:
*/
one_bit_t = (USEC_PER_SEC / clk_freq) + 1;
qup->one_byte_t = one_bit_t * 9;
+ qup->xfer_timeout = TOUT_MIN * HZ +
+ usecs_to_jiffies(MX_TX_RX_LEN * qup->one_byte_t);
dev_dbg(qup->dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
qup->in_blk_sz, qup->in_fifo_sz,