[media] drxk: Lock I2C bus during firmware load
authorMauro Carvalho Chehab <mchehab@redhat.com>
Fri, 29 Jun 2012 17:43:32 +0000 (14:43 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Fri, 29 Jun 2012 22:04:21 +0000 (19:04 -0300)
Don't allow other devices at the same I2C bus to use it during
firmware load, in order to prevent using the device while it is
not on a sane state.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/frontends/drxk_hard.c
drivers/media/dvb/frontends/drxk_hard.h

index 5b3a17ce3d1de2c751cc2bdb6c4801f27cfdbfd7..87cb3f02ebc024c73c0098f958c63c6cb7e75fce 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/delay.h>
 #include <linux/firmware.h>
 #include <linux/i2c.h>
+#include <linux/hardirq.h>
 #include <asm/div64.h>
 
 #include "dvb_frontend.h"
@@ -308,10 +309,30 @@ static u32 Log10Times100(u32 x)
 /* I2C **********************************************************************/
 /****************************************************************************/
 
+static int drxk_i2c_lock(struct drxk_state *state)
+{
+       i2c_lock_adapter(state->i2c);
+       state->drxk_i2c_exclusive_lock = true;
+
+       return 0;
+}
+
+static void drxk_i2c_unlock(struct drxk_state *state)
+{
+       if (!state->drxk_i2c_exclusive_lock)
+               return;
+
+       i2c_unlock_adapter(state->i2c);
+       state->drxk_i2c_exclusive_lock = false;
+}
+
 static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
                             unsigned len)
 {
-       return i2c_transfer(state->i2c, msgs, len);
+       if (state->drxk_i2c_exclusive_lock)
+               return __i2c_transfer(state->i2c, msgs, len);
+       else
+               return i2c_transfer(state->i2c, msgs, len);
 }
 
 static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
@@ -5982,6 +6003,7 @@ static int init_drxk(struct drxk_state *state)
 
        dprintk(1, "\n");
        if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
+               drxk_i2c_lock(state);
                status = PowerUpDevice(state);
                if (status < 0)
                        goto error;
@@ -6171,10 +6193,13 @@ static int init_drxk(struct drxk_state *state)
                        strlcat(state->frontend.ops.info.name, " DVB-T",
                                sizeof(state->frontend.ops.info.name));
                }
+               drxk_i2c_unlock(state);
        }
 error:
-       if (status < 0)
+       if (status < 0) {
+               drxk_i2c_unlock(state);
                printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+       }
 
        return status;
 }
index 36677cdc01d8718bb7cebcc9e0ba795f08ed0c30..c35ab2b37795f60b69528b08a0a265dcc297fb62 100644 (file)
@@ -325,6 +325,9 @@ struct drxk_state {
 
        enum DRXPowerMode m_currentPowerMode;
 
+       /* when true, avoids other devices to use the I2C bus */
+       bool              drxk_i2c_exclusive_lock;
+
        /*
         * Configurable parameters at the driver. They stores the values found
         * at struct drxk_config.