summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2015-04-21 09:58:15 -0300
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-08-11 07:32:58 -0300
commite14432a5b7302c1f5c6c094de176ae111697bbab (patch)
tree9e706487ac0369486ab34e01b14d4c1d8a0f010e
parent54ab48ed5db69212b9b6abc88d21cbbd5c16e7c3 (diff)
[media] tda10071: protect firmware command exec with mutex
There should be clearly some lock in order to make sure firmware command in execution is not disturbed by another command. It has worked as callbacks are serialized somehow pretty well and command execution happens usually without any delays. Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/dvb-frontends/tda10071.c12
-rw-r--r--drivers/media/dvb-frontends/tda10071_priv.h1
2 files changed, 10 insertions, 3 deletions
diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c
index 6226b579a440..84fb559e7b3d 100644
--- a/drivers/media/dvb-frontends/tda10071.c
+++ b/drivers/media/dvb-frontends/tda10071.c
@@ -61,25 +61,28 @@ static int tda10071_cmd_execute(struct tda10071_dev *dev,
goto error;
}
+ mutex_lock(&dev->cmd_execute_mutex);
+
/* write cmd and args for firmware */
ret = regmap_bulk_write(dev->regmap, 0x00, cmd->args, cmd->len);
if (ret)
- goto error;
+ goto error_mutex_unlock;
/* start cmd execution */
ret = regmap_write(dev->regmap, 0x1f, 1);
if (ret)
- goto error;
+ goto error_mutex_unlock;
/* wait cmd execution terminate */
for (i = 1000, uitmp = 1; i && uitmp; i--) {
ret = regmap_read(dev->regmap, 0x1f, &uitmp);
if (ret)
- goto error;
+ goto error_mutex_unlock;
usleep_range(200, 5000);
}
+ mutex_unlock(&dev->cmd_execute_mutex);
dev_dbg(&client->dev, "loop=%d\n", i);
if (i == 0) {
@@ -88,6 +91,8 @@ static int tda10071_cmd_execute(struct tda10071_dev *dev,
}
return ret;
+error_mutex_unlock:
+ mutex_unlock(&dev->cmd_execute_mutex);
error:
dev_dbg(&client->dev, "failed=%d\n", ret);
return ret;
@@ -1167,6 +1172,7 @@ static int tda10071_probe(struct i2c_client *client,
}
dev->client = client;
+ mutex_init(&dev->cmd_execute_mutex);
dev->clk = pdata->clk;
dev->i2c_wr_max = pdata->i2c_wr_max;
dev->ts_mode = pdata->ts_mode;
diff --git a/drivers/media/dvb-frontends/tda10071_priv.h b/drivers/media/dvb-frontends/tda10071_priv.h
index 30143c8f8bb8..cf5b43337136 100644
--- a/drivers/media/dvb-frontends/tda10071_priv.h
+++ b/drivers/media/dvb-frontends/tda10071_priv.h
@@ -30,6 +30,7 @@ struct tda10071_dev {
struct dvb_frontend fe;
struct i2c_client *client;
struct regmap *regmap;
+ struct mutex cmd_execute_mutex;
u32 clk;
u16 i2c_wr_max;
u8 ts_mode;