mirror of
https://github.com/torvalds/linux
synced 2024-09-19 18:46:35 +00:00
i2c-algo-bit: Fix spurious SCL timeouts under heavy load
When the system is under heavy load, there can be a significant delay between the getscl() and time_after() calls inside sclhi(). That delay may cause the time_after() check to trigger after SCL has gone high, causing sclhi() to return -ETIMEDOUT. To fix the problem, double check that SCL is still low after the timeout has been reached, before deciding to return -ETIMEDOUT. Signed-off-by: Ville Syrjala <syrjala@sci.fi> Cc: stable@vger.kernel.org Signed-off-by: Jean Delvare <khali@linux-fr.org>
This commit is contained in:
parent
834aa6f30c
commit
8ee161ce5e
|
@ -103,8 +103,14 @@ static int sclhi(struct i2c_algo_bit_data *adap)
|
||||||
* chips may hold it low ("clock stretching") while they
|
* chips may hold it low ("clock stretching") while they
|
||||||
* are processing data internally.
|
* are processing data internally.
|
||||||
*/
|
*/
|
||||||
if (time_after(jiffies, start + adap->timeout))
|
if (time_after(jiffies, start + adap->timeout)) {
|
||||||
|
/* Test one last time, as we may have been preempted
|
||||||
|
* between last check and timeout test.
|
||||||
|
*/
|
||||||
|
if (getscl(adap))
|
||||||
|
break;
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
cond_resched();
|
cond_resched();
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
Loading…
Reference in a new issue