compat: backport __i2c_transfer()
authorLuis R. Rodriguez <mcgrof@do-not-panic.com>
Wed, 10 Apr 2013 11:35:13 +0000 (04:35 -0700)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 10 Apr 2013 13:48:57 +0000 (15:48 +0200)
mcgrof@frijol ~/linux-stable (git::master)$ git describe --contains b37d2a3a
v3.6-rc1~28^2~265

commit b37d2a3a75cb0e72e18c29336cb2095b63dabfc8
Author: Jean Delvare <khali@linux-fr.org>
Date:   Fri Jun 29 07:47:19 2012 -0300

    [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>
Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
backport/compat/compat-3.6.c
backport/include/linux/compat-3.6.h

index a50fc987f56963a30249de97cefc6bd9ade8d53f..05954d451fa8a5eec8f34834a040d69c4241228a 100644 (file)
 #include <linux/export.h>
 #include <linux/bug.h>
 #include <linux/bitmap.h>
+#include <linux/i2c.h>
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+/**
+ * __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);
+#endif
 
 /**
  * memweight - count the total number of bits set in memory area
index bef0503aeff96b2a9023a107b7e6da0aa6f5ecf6..8fddd3108addffb131d05a5e5486c52f4a5f03cc 100644 (file)
@@ -7,6 +7,15 @@
 
 #include <linux/scatterlist.h>
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
+#include <linux/i2c.h>
+/* Unlocked flavor */
+#define __i2c_transfer LINUX_BACKPORT(__i2c_transfer)
+extern int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+                         int num);
+#endif
+
+
 #define memweight LINUX_BACKPORT(memweight)
 extern size_t memweight(const void *ptr, size_t bytes);