|
@@ -1294,6 +1294,37 @@ module_exit(i2c_exit);
|
|
|
* ----------------------------------------------------
|
|
|
*/
|
|
|
|
|
|
+/**
|
|
|
+ * __i2c_transfer - unlocked flavor of i2c_transfer
|
|
|
+ * @adap: Handle to I2C bus
|
|
|
+ * @msgs: One or more messages to execute before STOP is issued to
|
|
|
+ * terminate the operation; each message begins with a START.
|
|
|
+ * @num: Number of messages to be executed.
|
|
|
+ *
|
|
|
+ * Returns negative errno, else the number of messages executed.
|
|
|
+ *
|
|
|
+ * Adapter lock must be held when calling this function. No debug logging
|
|
|
+ * takes place. adap->algo->master_xfer existence isn't checked.
|
|
|
+ */
|
|
|
+int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
|
|
+{
|
|
|
+ unsigned long orig_jiffies;
|
|
|
+ int ret, try;
|
|
|
+
|
|
|
+ /* 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(__i2c_transfer);
|
|
|
+
|
|
|
/**
|
|
|
* i2c_transfer - execute a single or combined I2C message
|
|
|
* @adap: Handle to I2C bus
|
|
@@ -1308,8 +1339,7 @@ module_exit(i2c_exit);
|
|
|
*/
|
|
|
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
|
|
{
|
|
|
- unsigned long orig_jiffies;
|
|
|
- int ret, try;
|
|
|
+ int ret;
|
|
|
|
|
|
/* REVISIT the fault reporting model here is weak:
|
|
|
*
|
|
@@ -1347,15 +1377,7 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
|
|
|
i2c_lock_adapter(adap);
|
|
|
}
|
|
|
|
|
|
- /* 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;
|
|
|
- }
|
|
|
+ ret = __i2c_transfer(adap, msgs, num);
|
|
|
i2c_unlock_adapter(adap);
|
|
|
|
|
|
return ret;
|