Skip to content

Commit

Permalink
[media] cx25821: replace resource management functions with fh ownership
Browse files Browse the repository at this point in the history
Just remember which filehandle is streaming instead of using complicated
resource masks.
After this patch we can replace cx25821_fh with v4l2_fh.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Hans Verkuil authored and Mauro Carvalho Chehab committed Apr 16, 2013
1 parent 2efe2cc commit 84293f0
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 100 deletions.
130 changes: 34 additions & 96 deletions drivers/media/pci/cx25821/cx25821-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,48 +144,6 @@ static int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
return 0;
}

/* resource management */
static int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
unsigned int bit)
{
dprintk(1, "%s()\n", __func__);
if (fh->resources & bit)
/* have it already allocated */
return 1;

/* is it free? */
if (dev->channels[fh->channel_id].resources & bit) {
/* no, someone else uses it */
return 0;
}
/* it's free, grab it */
fh->resources |= bit;
dev->channels[fh->channel_id].resources |= bit;
dprintk(1, "res: get %d\n", bit);
return 1;
}

static int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit)
{
return fh->resources & bit;
}

static int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit)
{
return fh->dev->channels[fh->channel_id].resources & bit;
}

static void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
unsigned int bits)
{
BUG_ON((fh->resources & bits) != bits);
dprintk(1, "%s()\n", __func__);

fh->resources &= ~bits;
dev->channels[fh->channel_id].resources &= ~bits;
dprintk(1, "res: put %d\n", bits);
}

static int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
{
struct v4l2_routing route;
Expand Down Expand Up @@ -503,11 +461,6 @@ static void cx25821_buffer_release(struct videobuf_queue *q,
cx25821_free_buffer(q, buf);
}

static int cx25821_get_resource(struct cx25821_fh *fh, int resource)
{
return resource;
}

static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma)
{
struct cx25821_channel *chan = video_drvdata(file);
Expand Down Expand Up @@ -611,57 +564,45 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
struct cx25821_fh *fh = file->private_data;
struct cx25821_channel *chan = video_drvdata(file);
struct cx25821_dev *dev = fh->dev;
int err;
int err = 0;

if (mutex_lock_interruptible(&dev->lock))
return -ERESTARTSYS;
if (cx25821_res_locked(fh, RESOURCE_VIDEO0))
if (chan->streaming_fh && chan->streaming_fh != fh) {
err = -EBUSY;
else
err = videobuf_read_one(&chan->vidq, data, count, ppos,
goto unlock;
}
chan->streaming_fh = fh;

err = videobuf_read_one(&chan->vidq, data, count, ppos,
file->f_flags & O_NONBLOCK);
unlock:
mutex_unlock(&dev->lock);
return err;
}

static unsigned int video_poll(struct file *file,
struct poll_table_struct *wait)
{
struct cx25821_fh *fh = file->private_data;
struct cx25821_channel *chan = video_drvdata(file);
struct cx25821_buffer *buf;

if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
/* streaming capture */
if (list_empty(&chan->vidq.stream))
return POLLERR;
buf = list_entry(chan->vidq.stream.next,
struct cx25821_buffer, vb.stream);
} else {
/* read() capture */
buf = (struct cx25821_buffer *)chan->vidq.read_buf;
if (NULL == buf)
return POLLERR;
}
return videobuf_poll_stream(file, &chan->vidq, wait);

poll_wait(file, &buf->vb.done, wait);
if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
if (buf->vb.state == VIDEOBUF_DONE) {
struct cx25821_dev *dev = fh->dev;

if (dev && chan->use_cif_resolution) {
u8 cam_id = *((char *)buf->vb.baddr + 3);
memcpy((char *)buf->vb.baddr,
(char *)buf->vb.baddr + (chan->width * 2),
(chan->width * 2));
*((char *)buf->vb.baddr + 3) = cam_id;
}
}
/* This doesn't belong in poll(). This can be done
* much better with vb2. We keep this code here as a
* reminder.
if ((res & POLLIN) && buf->vb.state == VIDEOBUF_DONE) {
struct cx25821_dev *dev = chan->dev;
return POLLIN | POLLRDNORM;
if (dev && chan->use_cif_resolution) {
u8 cam_id = *((char *)buf->vb.baddr + 3);
memcpy((char *)buf->vb.baddr,
(char *)buf->vb.baddr + (chan->width * 2),
(chan->width * 2));
*((char *)buf->vb.baddr + 3) = cam_id;
}
}

return 0;
*/
}

static int video_release(struct file *file)
Expand All @@ -677,18 +618,18 @@ static int video_release(struct file *file)
cx_write(sram_ch->dma_ctl, 0); /* FIFO and RISC disable */

/* stop video capture */
if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
if (chan->streaming_fh == fh) {
videobuf_queue_cancel(&chan->vidq);
cx25821_res_free(dev, fh, RESOURCE_VIDEO0);
chan->streaming_fh = NULL;
}
mutex_unlock(&dev->lock);

if (chan->vidq.read_buf) {
cx25821_buffer_release(&chan->vidq, chan->vidq.read_buf);
kfree(chan->vidq.read_buf);
}

videobuf_mmap_free(&chan->vidq);
mutex_unlock(&dev->lock);

v4l2_prio_close(&chan->prio, fh->prio);
file->private_data = NULL;
Expand Down Expand Up @@ -765,14 +706,13 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
struct cx25821_channel *chan = video_drvdata(file);
struct cx25821_fh *fh = priv;
struct cx25821_dev *dev = fh->dev;

if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;

if (!cx25821_res_get(dev, fh,
cx25821_get_resource(fh, RESOURCE_VIDEO0)))
if (chan->streaming_fh && chan->streaming_fh != fh)
return -EBUSY;
chan->streaming_fh = fh;

return videobuf_streamon(&chan->vidq);
}
Expand All @@ -781,18 +721,17 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
{
struct cx25821_channel *chan = video_drvdata(file);
struct cx25821_fh *fh = priv;
struct cx25821_dev *dev = fh->dev;
int err, res;

if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;

res = cx25821_get_resource(fh, RESOURCE_VIDEO0);
err = videobuf_streamoff(&chan->vidq);
if (err < 0)
return err;
cx25821_res_free(dev, fh, res);
return 0;
if (chan->streaming_fh && chan->streaming_fh != fh)
return -EBUSY;
if (chan->streaming_fh == NULL)
return 0;

chan->streaming_fh = NULL;
return videobuf_streamoff(&chan->vidq);
}

static int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm)
Expand Down Expand Up @@ -1483,7 +1422,6 @@ int cx25821_video_register(struct cx25821_dev *dev)
chan->sram_channels->dma_ctl, 0x11, 0);

chan->sram_channels = &cx25821_sram_channels[i];
chan->resources = 0;
chan->width = 720;
if (dev->tvnorm & V4L2_STD_625_50)
chan->height = 576;
Expand Down
5 changes: 1 addition & 4 deletions drivers/media/pci/cx25821/cx25821.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ struct cx25821_tvnorm {

struct cx25821_fh {
struct cx25821_dev *dev;
u32 resources;

enum v4l2_priority prio;

Expand Down Expand Up @@ -208,6 +207,7 @@ struct cx25821_dev;
struct cx25821_channel {
unsigned id;
struct cx25821_dev *dev;
struct cx25821_fh *streaming_fh;
struct v4l2_prio_state prio;

struct v4l2_ctrl_handler hdl;
Expand All @@ -219,8 +219,6 @@ struct cx25821_channel {

const struct sram_channel *sram_channels;

int resources;

const struct cx25821_fmt *fmt;
unsigned int width, height;
int pixel_formats;
Expand Down Expand Up @@ -260,7 +258,6 @@ struct cx25821_dev {
char name[32];

/* Analog video */
u32 resources;
unsigned int input;
v4l2_std_id tvnorm;
unsigned short _max_num_decoders;
Expand Down

0 comments on commit 84293f0

Please sign in to comment.