Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84293f08 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

[media] cx25821: replace resource management functions with fh ownership



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: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 2efe2cc4
Loading
Loading
Loading
Loading
+34 −96
Original line number Original line Diff line number Diff line
@@ -144,48 +144,6 @@ static int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
	return 0;
	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)
static int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
{
{
	struct v4l2_routing route;
	struct v4l2_routing route;
@@ -503,11 +461,6 @@ static void cx25821_buffer_release(struct videobuf_queue *q,
	cx25821_free_buffer(q, buf);
	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)
static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma)
{
{
	struct cx25821_channel *chan = video_drvdata(file);
	struct cx25821_channel *chan = video_drvdata(file);
@@ -611,15 +564,19 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_channel *chan = video_drvdata(file);
	struct cx25821_channel *chan = video_drvdata(file);
	struct cx25821_dev *dev = fh->dev;
	struct cx25821_dev *dev = fh->dev;
	int err;
	int err = 0;


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

	err = videobuf_read_one(&chan->vidq, data, count, ppos,
	err = videobuf_read_one(&chan->vidq, data, count, ppos,
				file->f_flags & O_NONBLOCK);
				file->f_flags & O_NONBLOCK);
unlock:
	mutex_unlock(&dev->lock);
	mutex_unlock(&dev->lock);
	return err;
	return err;
}
}
@@ -627,27 +584,15 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
static unsigned int video_poll(struct file *file,
static unsigned int video_poll(struct file *file,
			      struct poll_table_struct *wait)
			      struct poll_table_struct *wait)
{
{
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_channel *chan = video_drvdata(file);
	struct cx25821_channel *chan = video_drvdata(file);
	struct cx25821_buffer *buf;


	if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
	return videobuf_poll_stream(file, &chan->vidq, wait);
		/* 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;
	}


	poll_wait(file, &buf->vb.done, wait);
	/* This doesn't belong in poll(). This can be done
	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
	 * much better with vb2. We keep this code here as a
		if (buf->vb.state == VIDEOBUF_DONE) {
	 * reminder.
			struct cx25821_dev *dev = fh->dev;
	if ((res & POLLIN) && buf->vb.state == VIDEOBUF_DONE) {
		struct cx25821_dev *dev = chan->dev;


		if (dev && chan->use_cif_resolution) {
		if (dev && chan->use_cif_resolution) {
			u8 cam_id = *((char *)buf->vb.baddr + 3);
			u8 cam_id = *((char *)buf->vb.baddr + 3);
@@ -657,11 +602,7 @@ static unsigned int video_poll(struct file *file,
			*((char *)buf->vb.baddr + 3) = cam_id;
			*((char *)buf->vb.baddr + 3) = cam_id;
		}
		}
	}
	}

	 */
		return POLLIN | POLLRDNORM;
	}

	return 0;
}
}


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


	/* stop video capture */
	/* stop video capture */
	if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
	if (chan->streaming_fh == fh) {
		videobuf_queue_cancel(&chan->vidq);
		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) {
	if (chan->vidq.read_buf) {
		cx25821_buffer_release(&chan->vidq, chan->vidq.read_buf);
		cx25821_buffer_release(&chan->vidq, chan->vidq.read_buf);
@@ -689,6 +629,7 @@ static int video_release(struct file *file)
	}
	}


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


	v4l2_prio_close(&chan->prio, fh->prio);
	v4l2_prio_close(&chan->prio, fh->prio);
	file->private_data = NULL;
	file->private_data = NULL;
@@ -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_channel *chan = video_drvdata(file);
	struct cx25821_fh *fh = priv;
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = fh->dev;


	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;
		return -EINVAL;


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


	return videobuf_streamon(&chan->vidq);
	return videobuf_streamon(&chan->vidq);
}
}
@@ -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_channel *chan = video_drvdata(file);
	struct cx25821_fh *fh = priv;
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = fh->dev;
	int err, res;


	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;
		return -EINVAL;


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

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


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


		chan->sram_channels = &cx25821_sram_channels[i];
		chan->sram_channels = &cx25821_sram_channels[i];
		chan->resources = 0;
		chan->width = 720;
		chan->width = 720;
		if (dev->tvnorm & V4L2_STD_625_50)
		if (dev->tvnorm & V4L2_STD_625_50)
			chan->height = 576;
			chan->height = 576;
+1 −4
Original line number Original line Diff line number Diff line
@@ -118,7 +118,6 @@ struct cx25821_tvnorm {


struct cx25821_fh {
struct cx25821_fh {
	struct cx25821_dev *dev;
	struct cx25821_dev *dev;
	u32 resources;


	enum v4l2_priority prio;
	enum v4l2_priority prio;


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


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


	const struct sram_channel *sram_channels;
	const struct sram_channel *sram_channels;


	int resources;

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


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