9
0
Fork 0

i2c: algo-bit: check if the bus is busy

If we have a timeout while waiting, try to recover.

Signed-off-by: Jan Luebbe <jluebbe@debian.org>
This commit is contained in:
Jan Luebbe 2015-07-30 16:41:15 +02:00
parent 8127dfdaa1
commit 39e4db8376
1 changed files with 32 additions and 0 deletions

View File

@ -117,6 +117,31 @@ done:
return 0;
}
static int wait_busy(struct i2c_algo_bit_data *adap)
{
uint64_t start;
if (sclhi(adap) < 0)
return -ETIMEDOUT;
start = get_time_ns();
while (!getsda(adap)) {
if (is_timeout(start, adap->timeout_ms * MSECOND)) {
if (getsda(adap))
break;
return -ETIMEDOUT;
}
}
#ifdef DEBUG
if ((get_time_ns() - start) < 10000)
pr_debug("i2c-algo-bit: needed %u usecs for SDA to go "
"high\n", (unsigned int)(get_time_ns() - start) /
1000);
#endif
udelay(adap->udelay);
return 0;
}
/* --- other auxiliary functions -------------------------------------- */
static void i2c_start(struct i2c_algo_bit_data *adap)
@ -512,6 +537,13 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
return ret;
}
if (wait_busy(adap) < 0) { /* timeout */
dev_warn(&i2c_adap->dev, "timeout waiting for bus ready\n");
ret = i2c_recover_bus(i2c_adap);
if (ret < 0)
return ret;
}
bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
i2c_start(adap);
for (i = 0; i < num; i++) {