diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-06-29 14:43:32 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-06-29 19:04:21 -0300 |
commit | 20bfe7ae089076b0af72a6d67f0298621ae90a9d (patch) | |
tree | 27c5aab38bcc6c34917098004055a0db70b54142 /drivers/media/dvb/frontends/drxk_hard.c | |
parent | 2a5f6720ff45e7545c3058bc6bfdb498247b4f5c (diff) | |
download | op-kernel-dev-20bfe7ae089076b0af72a6d67f0298621ae90a9d.zip op-kernel-dev-20bfe7ae089076b0af72a6d67f0298621ae90a9d.tar.gz |
[media] drxk: Lock I2C bus during firmware load
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>
Diffstat (limited to 'drivers/media/dvb/frontends/drxk_hard.c')
-rw-r--r-- | drivers/media/dvb/frontends/drxk_hard.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 5b3a17c..87cb3f0 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -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; } |