aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r--drivers/i2c/i2c-core.c43
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 */
1023int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) 1012int 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,