@@ -21,17 +21,20 @@ static const struct dvb_frontend_ops si2168_ops;
/* execute firmware command */
static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd)
{
+ struct si2168_dev *dev = i2c_get_clientdata(client);
int ret;
unsigned long timeout;
+ mutex_lock(&dev->i2c_mutex);
+
if (cmd->wlen) {
/* write cmd and args for firmware */
ret = i2c_master_send(client, cmd->args, cmd->wlen);
if (ret < 0) {
- goto err;
+ goto err_mutex_unlock;
} else if (ret != cmd->wlen) {
ret = -EREMOTEIO;
- goto err;
+ goto err_mutex_unlock;
}
}
@@ -42,10 +45,10 @@ static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd)
while (!time_after(jiffies, timeout)) {
ret = i2c_master_recv(client, cmd->args, cmd->rlen);
if (ret < 0) {
- goto err;
+ goto err_mutex_unlock;
} else if (ret != cmd->rlen) {
ret = -EREMOTEIO;
- goto err;
+ goto err_mutex_unlock;
}
/* firmware ready? */
@@ -60,17 +63,19 @@ static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd)
/* error bit set? */
if ((cmd->args[0] >> 6) & 0x01) {
ret = -EREMOTEIO;
- goto err;
+ goto err_mutex_unlock;
}
if (!((cmd->args[0] >> 7) & 0x01)) {
ret = -ETIMEDOUT;
- goto err;
+ goto err_mutex_unlock;
}
}
+ mutex_unlock(&dev->i2c_mutex);
return 0;
-err:
+err_mutex_unlock:
+ mutex_unlock(&dev->i2c_mutex);
dev_dbg(&client->dev, "failed=%d\n", ret);
return ret;
}
@@ -658,6 +663,8 @@ static int si2168_probe(struct i2c_client *client,
goto err;
}
+ mutex_init(&dev->i2c_mutex);
+
/* create mux i2c adapter for tuner */
dev->muxc = i2c_mux_one_adapter(client->adapter, &client->dev, 0,
I2C_MUX_SELF_LOCKED, 0, 0, 0,
@@ -29,6 +29,7 @@
/* state struct */
struct si2168_dev {
+ struct mutex i2c_mutex;
struct i2c_mux_core *muxc;
struct dvb_frontend fe;
enum fe_delivery_system delivery_system;
Mauro do not apply that patch, it is fix for Peter I2C-mux serie! Peter, please meld that fix to main patch: [media] si2168: declare that the i2c gate is self-locked We need lock to make sure only single caller could execute firmware command at the time. Earlier there was manual I2C locking which did the same job. Cc: Peter Rosin <peda@axentia.se> Signed-off-by: Antti Palosaari <crope@iki.fi> --- drivers/media/dvb-frontends/si2168.c | 21 ++++++++++++++------- drivers/media/dvb-frontends/si2168_priv.h | 1 + 2 files changed, 15 insertions(+), 7 deletions(-)