[media] tda10071: protect firmware command exec with mutex
authorAntti Palosaari <crope@iki.fi>
Tue, 21 Apr 2015 12:58:15 +0000 (09:58 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 11 Aug 2015 10:32:58 +0000 (07:32 -0300)
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>
drivers/media/dvb-frontends/tda10071.c
drivers/media/dvb-frontends/tda10071_priv.h

index 6226b579a4408a5851e959f0b5cc562799c504e1..84fb559e7b3d5c69e46ad771d4745866791ceaa9 100644 (file)
@@ -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;
index 30143c8f8bb83e5ef069267c3f4fe798200cb12e..cf5b43337136c52477180ee7ea320f3895e17db8 100644 (file)
@@ -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;