The old solution for i2c xfer timeout was to set timeout value to one second for all i2c xfer. That's not reasonable for various speed modes and data length.
This patch sets the xfer_read timeout value based on both bus speed and data length. Signed-off-by: Bin Yang <[email protected]> --- drivers/i2c/busses/i2c-mrst.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-mrst.c b/drivers/i2c/busses/i2c-mrst.c index 9d6d6c7..26c8f1c 100644 --- a/drivers/i2c/busses/i2c-mrst.c +++ b/drivers/i2c/busses/i2c-mrst.c @@ -71,6 +71,8 @@ static int speed_mode[6] = { static int ctl_num = 6; module_param_array(speed_mode, int, &ctl_num, S_IRUGO); +static const int xfer_timeout[NUM_SPEEDS] = {100, 25, 3}; + /** * mrst_i2c_disable - Disable I2C controller * @adap: struct pointer to i2c_adapter @@ -91,7 +93,6 @@ static int mrst_i2c_disable(struct i2c_adapter *adap) int count = 0; int ret1, ret2; - static const u16 delay[NUM_SPEEDS] = {100, 25, 3}; /* Set IC_ENABLE to 0 */ mrst_i2c_write(i2c->base + IC_ENABLE, 0); @@ -100,7 +101,7 @@ static int mrst_i2c_disable(struct i2c_adapter *adap) dev_dbg(&adap->dev, "mrst i2c disable\n"); while ((ret1 = mrst_i2c_read(i2c->base + IC_ENABLE_STATUS) & 0x1) || (ret2 = mrst_i2c_read(i2c->base + IC_STATUS) & 0x1)) { - udelay(delay[i2c->speed]); + udelay(xfer_timeout[i2c->speed]); mrst_i2c_write(i2c->base + IC_ENABLE, 0); dev_dbg(&adap->dev, "i2c is busy, count is %d speed %d\n", count, i2c->speed); @@ -352,7 +353,8 @@ static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length) while (i--) mrst_i2c_write(i2c->base + IC_DATA_CMD, (uint16_t)0x100); - err = wait_for_completion_interruptible_timeout(&i2c->complete, HZ); + err = wait_for_completion_interruptible_timeout(&i2c->complete, + msecs_to_jiffies(length * xfer_timeout[i2c->speed])); if (!err) { dev_err(&adap->dev, "%s: Time out for ACK from I2C slave device 0x%x\n", @@ -409,7 +411,8 @@ static int xfer_write(struct i2c_adapter *adap, mrst_i2c_write(i2c->base + IC_DATA_CMD, (uint16_t)(*(buf + i))); - err = wait_for_completion_interruptible_timeout(&i2c->complete, HZ); + err = wait_for_completion_interruptible_timeout(&i2c->complete, + msecs_to_jiffies(length * xfer_timeout[i2c->speed])); if (!err) { dev_err(&adap->dev, "%s: Time out for ACK from I2C slave device 0x%x\n", -- 1.7.0.4 _______________________________________________ MeeGo-kernel mailing list [email protected] http://lists.meego.com/listinfo/meego-kernel
