aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2012-06-29 06:47:19 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-06-29 18:03:25 -0400
commitb37d2a3a75cb0e72e18c29336cb2095b63dabfc8 (patch)
tree212e01d73f40881626b54ef4811de3a061788989 /drivers/i2c
parenta99817ca60d206be3645d156f755cf065e949c58 (diff)
[media] i2c: Export an unlocked flavor of i2c_transfer
Some drivers (in particular for TV cards) need exclusive access to their I2C buses for specific operations. Export an unlocked flavor of i2c_transfer to give them full control. The unlocked flavor has the following limitations: * Obviously, caller must hold the i2c adapter lock. * No debug messages are logged. We don't want to log messages while holding a rt_mutex. * No check is done on the existence of adap->algo->master_xfer. It is thus the caller's responsibility to ensure that the function is OK to call. Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/i2c-core.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index feb7dc359186..ccc6445979c4 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1295,6 +1295,37 @@ module_exit(i2c_exit);
1295 */ 1295 */
1296 1296
1297/** 1297/**
1298 * __i2c_transfer - unlocked flavor of i2c_transfer
1299 * @adap: Handle to I2C bus
1300 * @msgs: One or more messages to execute before STOP is issued to
1301 * terminate the operation; each message begins with a START.
1302 * @num: Number of messages to be executed.
1303 *
1304 * Returns negative errno, else the number of messages executed.
1305 *
1306 * Adapter lock must be held when calling this function. No debug logging
1307 * takes place. adap->algo->master_xfer existence isn't checked.
1308 */
1309int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
1310{
1311 unsigned long orig_jiffies;
1312 int ret, try;
1313
1314 /* Retry automatically on arbitration loss */
1315 orig_jiffies = jiffies;
1316 for (ret = 0, try = 0; try <= adap->retries; try++) {
1317 ret = adap->algo->master_xfer(adap, msgs, num);
1318 if (ret != -EAGAIN)
1319 break;
1320 if (time_after(jiffies, orig_jiffies + adap->timeout))
1321 break;
1322 }
1323
1324 return ret;
1325}
1326EXPORT_SYMBOL(__i2c_transfer);
1327
1328/**
1298 * i2c_transfer - execute a single or combined I2C message 1329 * i2c_transfer - execute a single or combined I2C message
1299 * @adap: Handle to I2C bus 1330 * @adap: Handle to I2C bus
1300 * @msgs: One or more messages to execute before STOP is issued to 1331 * @msgs: One or more messages to execute before STOP is issued to
@@ -1308,8 +1339,7 @@ module_exit(i2c_exit);
1308 */ 1339 */
1309int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) 1340int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
1310{ 1341{
1311 unsigned long orig_jiffies; 1342 int ret;
1312 int ret, try;
1313 1343
1314 /* REVISIT the fault reporting model here is weak: 1344 /* REVISIT the fault reporting model here is weak:
1315 * 1345 *
@@ -1347,15 +1377,7 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
1347 i2c_lock_adapter(adap); 1377 i2c_lock_adapter(adap);
1348 } 1378 }
1349 1379
1350 /* Retry automatically on arbitration loss */ 1380 ret = __i2c_transfer(adap, msgs, num);
1351 orig_jiffies = jiffies;
1352 for (ret = 0, try = 0; try <= adap->retries; try++) {
1353 ret = adap->algo->master_xfer(adap, msgs, num);
1354 if (ret != -EAGAIN)
1355 break;
1356 if (time_after(jiffies, orig_jiffies + adap->timeout))
1357 break;
1358 }
1359 i2c_unlock_adapter(adap); 1381 i2c_unlock_adapter(adap);
1360 1382
1361 return ret; 1383 return ret;