Commit 20bfe7ae authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

[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: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 2a5f6720
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/hardirq.h>
#include <asm/div64.h> #include <asm/div64.h>
#include "dvb_frontend.h" #include "dvb_frontend.h"
...@@ -308,9 +309,29 @@ static u32 Log10Times100(u32 x) ...@@ -308,9 +309,29 @@ static u32 Log10Times100(u32 x)
/* I2C **********************************************************************/ /* 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, static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
unsigned len) unsigned len)
{ {
if (state->drxk_i2c_exclusive_lock)
return __i2c_transfer(state->i2c, msgs, len);
else
return i2c_transfer(state->i2c, msgs, len); return i2c_transfer(state->i2c, msgs, len);
} }
...@@ -5982,6 +6003,7 @@ static int init_drxk(struct drxk_state *state) ...@@ -5982,6 +6003,7 @@ static int init_drxk(struct drxk_state *state)
dprintk(1, "\n"); dprintk(1, "\n");
if ((state->m_DrxkState == DRXK_UNINITIALIZED)) { if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
drxk_i2c_lock(state);
status = PowerUpDevice(state); status = PowerUpDevice(state);
if (status < 0) if (status < 0)
goto error; goto error;
...@@ -6171,10 +6193,13 @@ static int init_drxk(struct drxk_state *state) ...@@ -6171,10 +6193,13 @@ static int init_drxk(struct drxk_state *state)
strlcat(state->frontend.ops.info.name, " DVB-T", strlcat(state->frontend.ops.info.name, " DVB-T",
sizeof(state->frontend.ops.info.name)); sizeof(state->frontend.ops.info.name));
} }
drxk_i2c_unlock(state);
} }
error: error:
if (status < 0) if (status < 0) {
drxk_i2c_unlock(state);
printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
}
return status; return status;
} }
......
...@@ -325,6 +325,9 @@ struct drxk_state { ...@@ -325,6 +325,9 @@ struct drxk_state {
enum DRXPowerMode m_currentPowerMode; 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 * Configurable parameters at the driver. They stores the values found
* at struct drxk_config. * at struct drxk_config.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment