Skip to content

Commit

Permalink
[media] media: coda: keep track of active instances
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Philipp Zabel authored and Mauro Carvalho Chehab committed Sep 26, 2012
1 parent bcedb4c commit e11f3e6
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions drivers/media/platform/coda.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ struct coda_dev {
struct mutex dev_mutex;
struct v4l2_m2m_dev *m2m_dev;
struct vb2_alloc_ctx *alloc_ctx;
int instances;
struct list_head instances;
unsigned long instance_mask;
};

struct coda_params {
Expand All @@ -152,6 +153,7 @@ struct coda_params {

struct coda_ctx {
struct coda_dev *dev;
struct list_head list;
int aborting;
int rawstreamon;
int compstreamon;
Expand Down Expand Up @@ -1360,14 +1362,22 @@ static int coda_queue_init(void *priv, struct vb2_queue *src_vq,
return vb2_queue_init(dst_vq);
}

static int coda_next_free_instance(struct coda_dev *dev)
{
return ffz(dev->instance_mask);
}

static int coda_open(struct file *file)
{
struct coda_dev *dev = video_drvdata(file);
struct coda_ctx *ctx = NULL;
int ret = 0;
int idx;

if (dev->instances >= CODA_MAX_INSTANCES)
idx = coda_next_free_instance(dev);
if (idx >= CODA_MAX_INSTANCES)
return -EBUSY;
set_bit(idx, &dev->instance_mask);

ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
if (!ctx)
Expand All @@ -1377,6 +1387,7 @@ static int coda_open(struct file *file)
file->private_data = &ctx->fh;
v4l2_fh_add(&ctx->fh);
ctx->dev = dev;
ctx->idx = idx;

set_default_params(ctx);
ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
Expand Down Expand Up @@ -1405,7 +1416,7 @@ static int coda_open(struct file *file)
}

coda_lock(ctx);
ctx->idx = dev->instances++;
list_add(&ctx->list, &dev->instances);
coda_unlock(ctx);

clk_prepare_enable(dev->clk_per);
Expand All @@ -1432,7 +1443,7 @@ static int coda_release(struct file *file)
ctx);

coda_lock(ctx);
dev->instances--;
list_del(&ctx->list);
coda_unlock(ctx);

dma_free_coherent(&dev->plat_dev->dev, CODA_PARA_BUF_SIZE,
Expand All @@ -1443,6 +1454,7 @@ static int coda_release(struct file *file)
clk_disable_unprepare(dev->clk_ahb);
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
clear_bit(ctx->idx, &dev->instance_mask);
kfree(ctx);

return 0;
Expand Down Expand Up @@ -1826,6 +1838,7 @@ static int __devinit coda_probe(struct platform_device *pdev)
}

spin_lock_init(&dev->irqlock);
INIT_LIST_HEAD(&dev->instances);

dev->plat_dev = pdev;
dev->clk_per = devm_clk_get(&pdev->dev, "per");
Expand Down

0 comments on commit e11f3e6

Please sign in to comment.