diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2012-07-25 08:16:58 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-09-26 15:36:57 -0400 |
commit | e11f3e6ef64726c64dae435f7059715adf5de2ff (patch) | |
tree | bf7cc6d55810ea550c1e0c75584d871f651b8c88 | |
parent | bcedb4c2422801e37c3d9c716597e8883d1b4e87 (diff) |
[media] media: coda: keep track of active instances
Determining the next free instance just by incrementing and decrementing
an instance counter does not work: if there are two instances opened,
0 and 1, and instance 0 is released, the next call to coda_open will
create a new instance with index 1, but instance 1 is already in use.
Instead, scan a bitfield of active instances to determine the first
free instance index.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Tested-by: Javier Martin <javier.martin@vista-silicon.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/platform/coda.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index 01a8fe3e17f9..176741c3941c 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c | |||
@@ -134,7 +134,8 @@ struct coda_dev { | |||
134 | struct mutex dev_mutex; | 134 | struct mutex dev_mutex; |
135 | struct v4l2_m2m_dev *m2m_dev; | 135 | struct v4l2_m2m_dev *m2m_dev; |
136 | struct vb2_alloc_ctx *alloc_ctx; | 136 | struct vb2_alloc_ctx *alloc_ctx; |
137 | int instances; | 137 | struct list_head instances; |
138 | unsigned long instance_mask; | ||
138 | }; | 139 | }; |
139 | 140 | ||
140 | struct coda_params { | 141 | struct coda_params { |
@@ -152,6 +153,7 @@ struct coda_params { | |||
152 | 153 | ||
153 | struct coda_ctx { | 154 | struct coda_ctx { |
154 | struct coda_dev *dev; | 155 | struct coda_dev *dev; |
156 | struct list_head list; | ||
155 | int aborting; | 157 | int aborting; |
156 | int rawstreamon; | 158 | int rawstreamon; |
157 | int compstreamon; | 159 | int compstreamon; |
@@ -1360,14 +1362,22 @@ static int coda_queue_init(void *priv, struct vb2_queue *src_vq, | |||
1360 | return vb2_queue_init(dst_vq); | 1362 | return vb2_queue_init(dst_vq); |
1361 | } | 1363 | } |
1362 | 1364 | ||
1365 | static int coda_next_free_instance(struct coda_dev *dev) | ||
1366 | { | ||
1367 | return ffz(dev->instance_mask); | ||
1368 | } | ||
1369 | |||
1363 | static int coda_open(struct file *file) | 1370 | static int coda_open(struct file *file) |
1364 | { | 1371 | { |
1365 | struct coda_dev *dev = video_drvdata(file); | 1372 | struct coda_dev *dev = video_drvdata(file); |
1366 | struct coda_ctx *ctx = NULL; | 1373 | struct coda_ctx *ctx = NULL; |
1367 | int ret = 0; | 1374 | int ret = 0; |
1375 | int idx; | ||
1368 | 1376 | ||
1369 | if (dev->instances >= CODA_MAX_INSTANCES) | 1377 | idx = coda_next_free_instance(dev); |
1378 | if (idx >= CODA_MAX_INSTANCES) | ||
1370 | return -EBUSY; | 1379 | return -EBUSY; |
1380 | set_bit(idx, &dev->instance_mask); | ||
1371 | 1381 | ||
1372 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); | 1382 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); |
1373 | if (!ctx) | 1383 | if (!ctx) |
@@ -1377,6 +1387,7 @@ static int coda_open(struct file *file) | |||
1377 | file->private_data = &ctx->fh; | 1387 | file->private_data = &ctx->fh; |
1378 | v4l2_fh_add(&ctx->fh); | 1388 | v4l2_fh_add(&ctx->fh); |
1379 | ctx->dev = dev; | 1389 | ctx->dev = dev; |
1390 | ctx->idx = idx; | ||
1380 | 1391 | ||
1381 | set_default_params(ctx); | 1392 | set_default_params(ctx); |
1382 | ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, | 1393 | ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, |
@@ -1405,7 +1416,7 @@ static int coda_open(struct file *file) | |||
1405 | } | 1416 | } |
1406 | 1417 | ||
1407 | coda_lock(ctx); | 1418 | coda_lock(ctx); |
1408 | ctx->idx = dev->instances++; | 1419 | list_add(&ctx->list, &dev->instances); |
1409 | coda_unlock(ctx); | 1420 | coda_unlock(ctx); |
1410 | 1421 | ||
1411 | clk_prepare_enable(dev->clk_per); | 1422 | clk_prepare_enable(dev->clk_per); |
@@ -1432,7 +1443,7 @@ static int coda_release(struct file *file) | |||
1432 | ctx); | 1443 | ctx); |
1433 | 1444 | ||
1434 | coda_lock(ctx); | 1445 | coda_lock(ctx); |
1435 | dev->instances--; | 1446 | list_del(&ctx->list); |
1436 | coda_unlock(ctx); | 1447 | coda_unlock(ctx); |
1437 | 1448 | ||
1438 | dma_free_coherent(&dev->plat_dev->dev, CODA_PARA_BUF_SIZE, | 1449 | dma_free_coherent(&dev->plat_dev->dev, CODA_PARA_BUF_SIZE, |
@@ -1443,6 +1454,7 @@ static int coda_release(struct file *file) | |||
1443 | clk_disable_unprepare(dev->clk_ahb); | 1454 | clk_disable_unprepare(dev->clk_ahb); |
1444 | v4l2_fh_del(&ctx->fh); | 1455 | v4l2_fh_del(&ctx->fh); |
1445 | v4l2_fh_exit(&ctx->fh); | 1456 | v4l2_fh_exit(&ctx->fh); |
1457 | clear_bit(ctx->idx, &dev->instance_mask); | ||
1446 | kfree(ctx); | 1458 | kfree(ctx); |
1447 | 1459 | ||
1448 | return 0; | 1460 | return 0; |
@@ -1826,6 +1838,7 @@ static int __devinit coda_probe(struct platform_device *pdev) | |||
1826 | } | 1838 | } |
1827 | 1839 | ||
1828 | spin_lock_init(&dev->irqlock); | 1840 | spin_lock_init(&dev->irqlock); |
1841 | INIT_LIST_HEAD(&dev->instances); | ||
1829 | 1842 | ||
1830 | dev->plat_dev = pdev; | 1843 | dev->plat_dev = pdev; |
1831 | dev->clk_per = devm_clk_get(&pdev->dev, "per"); | 1844 | dev->clk_per = devm_clk_get(&pdev->dev, "per"); |