mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-30 19:15:14 +00:00
i2c: Retry automatically on arbitration loss
Some small changes in i2c core to retry i2c xfers until either the maximum number of retries or the timeout is hit. Signed-off-by: Clifford Wolf <clifford@clifford.at> Signed-off-by: Jean Delvare <khali@linux-fr.org>
This commit is contained in:
parent
1cf92b453a
commit
66b650f045
1 changed files with 26 additions and 4 deletions
|
@ -1022,7 +1022,8 @@ module_exit(i2c_exit);
|
||||||
*/
|
*/
|
||||||
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
||||||
{
|
{
|
||||||
int ret;
|
unsigned long orig_jiffies;
|
||||||
|
int ret, try;
|
||||||
|
|
||||||
/* REVISIT the fault reporting model here is weak:
|
/* REVISIT the fault reporting model here is weak:
|
||||||
*
|
*
|
||||||
|
@ -1060,7 +1061,15 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
||||||
mutex_lock_nested(&adap->bus_lock, adap->level);
|
mutex_lock_nested(&adap->bus_lock, adap->level);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = adap->algo->master_xfer(adap,msgs,num);
|
/* Retry automatically on arbitration loss */
|
||||||
|
orig_jiffies = jiffies;
|
||||||
|
for (ret = 0, try = 0; try <= adap->retries; try++) {
|
||||||
|
ret = adap->algo->master_xfer(adap, msgs, num);
|
||||||
|
if (ret != -EAGAIN)
|
||||||
|
break;
|
||||||
|
if (time_after(jiffies, orig_jiffies + adap->timeout))
|
||||||
|
break;
|
||||||
|
}
|
||||||
mutex_unlock(&adap->bus_lock);
|
mutex_unlock(&adap->bus_lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1995,14 +2004,27 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
|
||||||
char read_write, u8 command, int protocol,
|
char read_write, u8 command, int protocol,
|
||||||
union i2c_smbus_data *data)
|
union i2c_smbus_data *data)
|
||||||
{
|
{
|
||||||
|
unsigned long orig_jiffies;
|
||||||
|
int try;
|
||||||
s32 res;
|
s32 res;
|
||||||
|
|
||||||
flags &= I2C_M_TEN | I2C_CLIENT_PEC;
|
flags &= I2C_M_TEN | I2C_CLIENT_PEC;
|
||||||
|
|
||||||
if (adapter->algo->smbus_xfer) {
|
if (adapter->algo->smbus_xfer) {
|
||||||
mutex_lock(&adapter->bus_lock);
|
mutex_lock(&adapter->bus_lock);
|
||||||
res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write,
|
|
||||||
command, protocol, data);
|
/* Retry automatically on arbitration loss */
|
||||||
|
orig_jiffies = jiffies;
|
||||||
|
for (res = 0, try = 0; try <= adapter->retries; try++) {
|
||||||
|
res = adapter->algo->smbus_xfer(adapter, addr, flags,
|
||||||
|
read_write, command,
|
||||||
|
protocol, data);
|
||||||
|
if (res != -EAGAIN)
|
||||||
|
break;
|
||||||
|
if (time_after(jiffies,
|
||||||
|
orig_jiffies + adapter->timeout))
|
||||||
|
break;
|
||||||
|
}
|
||||||
mutex_unlock(&adapter->bus_lock);
|
mutex_unlock(&adapter->bus_lock);
|
||||||
} else
|
} else
|
||||||
res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
|
res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
|
||||||
|
|
Loading…
Add table
Reference in a new issue