diff options
Diffstat (limited to 'drivers/i2c/i2c-core.c')
| -rw-r--r-- | drivers/i2c/i2c-core.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 85e2e919d1cd..5ed622ee65c3 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
| 30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
| 31 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
| 32 | #include <linux/platform_device.h> | ||
| 33 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
| 34 | #include <linux/completion.h> | 33 | #include <linux/completion.h> |
| 35 | #include <linux/hardirq.h> | 34 | #include <linux/hardirq.h> |
| @@ -451,16 +450,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap) | |||
| 451 | 450 | ||
| 452 | mutex_lock(&core_lock); | 451 | mutex_lock(&core_lock); |
| 453 | 452 | ||
| 454 | /* Add the adapter to the driver core. | ||
| 455 | * If the parent pointer is not set up, | ||
| 456 | * we add this adapter to the host bus. | ||
| 457 | */ | ||
| 458 | if (adap->dev.parent == NULL) { | ||
| 459 | adap->dev.parent = &platform_bus; | ||
| 460 | pr_debug("I2C adapter driver [%s] forgot to specify " | ||
| 461 | "physical device\n", adap->name); | ||
| 462 | } | ||
| 463 | |||
| 464 | /* Set default timeout to 1 second if not already set */ | 453 | /* Set default timeout to 1 second if not already set */ |
| 465 | if (adap->timeout == 0) | 454 | if (adap->timeout == 0) |
| 466 | adap->timeout = HZ; | 455 | adap->timeout = HZ; |
| @@ -1022,7 +1011,8 @@ module_exit(i2c_exit); | |||
| 1022 | */ | 1011 | */ |
| 1023 | int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | 1012 | int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) |
| 1024 | { | 1013 | { |
| 1025 | int ret; | 1014 | unsigned long orig_jiffies; |
| 1015 | int ret, try; | ||
| 1026 | 1016 | ||
| 1027 | /* REVISIT the fault reporting model here is weak: | 1017 | /* REVISIT the fault reporting model here is weak: |
| 1028 | * | 1018 | * |
| @@ -1060,7 +1050,15 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
| 1060 | mutex_lock_nested(&adap->bus_lock, adap->level); | 1050 | mutex_lock_nested(&adap->bus_lock, adap->level); |
| 1061 | } | 1051 | } |
| 1062 | 1052 | ||
| 1063 | ret = adap->algo->master_xfer(adap,msgs,num); | 1053 | /* Retry automatically on arbitration loss */ |
| 1054 | orig_jiffies = jiffies; | ||
| 1055 | for (ret = 0, try = 0; try <= adap->retries; try++) { | ||
| 1056 | ret = adap->algo->master_xfer(adap, msgs, num); | ||
| 1057 | if (ret != -EAGAIN) | ||
| 1058 | break; | ||
| 1059 | if (time_after(jiffies, orig_jiffies + adap->timeout)) | ||
| 1060 | break; | ||
| 1061 | } | ||
| 1064 | mutex_unlock(&adap->bus_lock); | 1062 | mutex_unlock(&adap->bus_lock); |
| 1065 | 1063 | ||
| 1066 | return ret; | 1064 | return ret; |
| @@ -1509,7 +1507,7 @@ struct i2c_adapter* i2c_get_adapter(int id) | |||
| 1509 | struct i2c_adapter *adapter; | 1507 | struct i2c_adapter *adapter; |
| 1510 | 1508 | ||
| 1511 | mutex_lock(&core_lock); | 1509 | mutex_lock(&core_lock); |
| 1512 | adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id); | 1510 | adapter = idr_find(&i2c_adapter_idr, id); |
| 1513 | if (adapter && !try_module_get(adapter->owner)) | 1511 | if (adapter && !try_module_get(adapter->owner)) |
| 1514 | adapter = NULL; | 1512 | adapter = NULL; |
| 1515 | 1513 | ||
| @@ -1995,14 +1993,27 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, | |||
| 1995 | char read_write, u8 command, int protocol, | 1993 | char read_write, u8 command, int protocol, |
| 1996 | union i2c_smbus_data *data) | 1994 | union i2c_smbus_data *data) |
| 1997 | { | 1995 | { |
| 1996 | unsigned long orig_jiffies; | ||
| 1997 | int try; | ||
| 1998 | s32 res; | 1998 | s32 res; |
| 1999 | 1999 | ||
| 2000 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; | 2000 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; |
| 2001 | 2001 | ||
| 2002 | if (adapter->algo->smbus_xfer) { | 2002 | if (adapter->algo->smbus_xfer) { |
| 2003 | mutex_lock(&adapter->bus_lock); | 2003 | mutex_lock(&adapter->bus_lock); |
| 2004 | res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, | 2004 | |
| 2005 | command, protocol, data); | 2005 | /* Retry automatically on arbitration loss */ |
| 2006 | orig_jiffies = jiffies; | ||
| 2007 | for (res = 0, try = 0; try <= adapter->retries; try++) { | ||
| 2008 | res = adapter->algo->smbus_xfer(adapter, addr, flags, | ||
| 2009 | read_write, command, | ||
| 2010 | protocol, data); | ||
| 2011 | if (res != -EAGAIN) | ||
| 2012 | break; | ||
| 2013 | if (time_after(jiffies, | ||
| 2014 | orig_jiffies + adapter->timeout)) | ||
| 2015 | break; | ||
| 2016 | } | ||
| 2006 | mutex_unlock(&adapter->bus_lock); | 2017 | mutex_unlock(&adapter->bus_lock); |
| 2007 | } else | 2018 | } else |
| 2008 | res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, | 2019 | res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, |
