aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-04-14 10:56:39 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-16 17:07:13 -0400
commit84293f0843931b13d8331093bafacd1d70dd5efb (patch)
tree5cc43ab7d463a478578c4ed89933013bb4a02247 /drivers/media
parent2efe2cc4305ad9a8ea4db5881808c4db1c451091 (diff)
[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: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/pci/cx25821/cx25821-video.c130
-rw-r--r--drivers/media/pci/cx25821/cx25821.h5
2 files changed, 35 insertions, 100 deletions
diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c
index d88316c5f5de..e7a2db158a0e 100644
--- a/drivers/media/pci/cx25821/cx25821-video.c
+++ b/drivers/media/pci/cx25821/cx25821-video.c
@@ -144,48 +144,6 @@ static int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
144 return 0; 144 return 0;
145} 145}
146 146
147/* resource management */
148static int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
149 unsigned int bit)
150{
151 dprintk(1, "%s()\n", __func__);
152 if (fh->resources & bit)
153 /* have it already allocated */
154 return 1;
155
156 /* is it free? */
157 if (dev->channels[fh->channel_id].resources & bit) {
158 /* no, someone else uses it */
159 return 0;
160 }
161 /* it's free, grab it */
162 fh->resources |= bit;
163 dev->channels[fh->channel_id].resources |= bit;
164 dprintk(1, "res: get %d\n", bit);
165 return 1;
166}
167
168static int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit)
169{
170 return fh->resources & bit;
171}
172
173static int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit)
174{
175 return fh->dev->channels[fh->channel_id].resources & bit;
176}
177
178static void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
179 unsigned int bits)
180{
181 BUG_ON((fh->resources & bits) != bits);
182 dprintk(1, "%s()\n", __func__);
183
184 fh->resources &= ~bits;
185 dev->channels[fh->channel_id].resources &= ~bits;
186 dprintk(1, "res: put %d\n", bits);
187}
188
189static int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input) 147static int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
190{ 148{
191 struct v4l2_routing route; 149 struct v4l2_routing route;
@@ -503,11 +461,6 @@ static void cx25821_buffer_release(struct videobuf_queue *q,
503 cx25821_free_buffer(q, buf); 461 cx25821_free_buffer(q, buf);
504} 462}
505 463
506static int cx25821_get_resource(struct cx25821_fh *fh, int resource)
507{
508 return resource;
509}
510
511static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma) 464static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma)
512{ 465{
513 struct cx25821_channel *chan = video_drvdata(file); 466 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,
611 struct cx25821_fh *fh = file->private_data; 564 struct cx25821_fh *fh = file->private_data;
612 struct cx25821_channel *chan = video_drvdata(file); 565 struct cx25821_channel *chan = video_drvdata(file);
613 struct cx25821_dev *dev = fh->dev; 566 struct cx25821_dev *dev = fh->dev;
614 int err; 567 int err = 0;
615 568
616 if (mutex_lock_interruptible(&dev->lock)) 569 if (mutex_lock_interruptible(&dev->lock))
617 return -ERESTARTSYS; 570 return -ERESTARTSYS;
618 if (cx25821_res_locked(fh, RESOURCE_VIDEO0)) 571 if (chan->streaming_fh && chan->streaming_fh != fh) {
619 err = -EBUSY; 572 err = -EBUSY;
620 else 573 goto unlock;
621 err = videobuf_read_one(&chan->vidq, data, count, ppos, 574 }
575 chan->streaming_fh = fh;
576
577 err = videobuf_read_one(&chan->vidq, data, count, ppos,
622 file->f_flags & O_NONBLOCK); 578 file->f_flags & O_NONBLOCK);
579unlock:
623 mutex_unlock(&dev->lock); 580 mutex_unlock(&dev->lock);
624 return err; 581 return err;
625} 582}
@@ -627,41 +584,25 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count,
627static unsigned int video_poll(struct file *file, 584static unsigned int video_poll(struct file *file,
628 struct poll_table_struct *wait) 585 struct poll_table_struct *wait)
629{ 586{
630 struct cx25821_fh *fh = file->private_data;
631 struct cx25821_channel *chan = video_drvdata(file); 587 struct cx25821_channel *chan = video_drvdata(file);
632 struct cx25821_buffer *buf;
633 588
634 if (cx25821_res_check(fh, RESOURCE_VIDEO0)) { 589 return videobuf_poll_stream(file, &chan->vidq, wait);
635 /* streaming capture */
636 if (list_empty(&chan->vidq.stream))
637 return POLLERR;
638 buf = list_entry(chan->vidq.stream.next,
639 struct cx25821_buffer, vb.stream);
640 } else {
641 /* read() capture */
642 buf = (struct cx25821_buffer *)chan->vidq.read_buf;
643 if (NULL == buf)
644 return POLLERR;
645 }
646 590
647 poll_wait(file, &buf->vb.done, wait); 591 /* This doesn't belong in poll(). This can be done
648 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) { 592 * much better with vb2. We keep this code here as a
649 if (buf->vb.state == VIDEOBUF_DONE) { 593 * reminder.
650 struct cx25821_dev *dev = fh->dev; 594 if ((res & POLLIN) && buf->vb.state == VIDEOBUF_DONE) {
651 595 struct cx25821_dev *dev = chan->dev;
652 if (dev && chan->use_cif_resolution) {
653 u8 cam_id = *((char *)buf->vb.baddr + 3);
654 memcpy((char *)buf->vb.baddr,
655 (char *)buf->vb.baddr + (chan->width * 2),
656 (chan->width * 2));
657 *((char *)buf->vb.baddr + 3) = cam_id;
658 }
659 }
660 596
661 return POLLIN | POLLRDNORM; 597 if (dev && chan->use_cif_resolution) {
598 u8 cam_id = *((char *)buf->vb.baddr + 3);
599 memcpy((char *)buf->vb.baddr,
600 (char *)buf->vb.baddr + (chan->width * 2),
601 (chan->width * 2));
602 *((char *)buf->vb.baddr + 3) = cam_id;
603 }
662 } 604 }
663 605 */
664 return 0;
665} 606}
666 607
667static int video_release(struct file *file) 608static int video_release(struct file *file)
@@ -677,11 +618,10 @@ static int video_release(struct file *file)
677 cx_write(sram_ch->dma_ctl, 0); /* FIFO and RISC disable */ 618 cx_write(sram_ch->dma_ctl, 0); /* FIFO and RISC disable */
678 619
679 /* stop video capture */ 620 /* stop video capture */
680 if (cx25821_res_check(fh, RESOURCE_VIDEO0)) { 621 if (chan->streaming_fh == fh) {
681 videobuf_queue_cancel(&chan->vidq); 622 videobuf_queue_cancel(&chan->vidq);
682 cx25821_res_free(dev, fh, RESOURCE_VIDEO0); 623 chan->streaming_fh = NULL;
683 } 624 }
684 mutex_unlock(&dev->lock);
685 625
686 if (chan->vidq.read_buf) { 626 if (chan->vidq.read_buf) {
687 cx25821_buffer_release(&chan->vidq, chan->vidq.read_buf); 627 cx25821_buffer_release(&chan->vidq, chan->vidq.read_buf);
@@ -689,6 +629,7 @@ static int video_release(struct file *file)
689 } 629 }
690 630
691 videobuf_mmap_free(&chan->vidq); 631 videobuf_mmap_free(&chan->vidq);
632 mutex_unlock(&dev->lock);
692 633
693 v4l2_prio_close(&chan->prio, fh->prio); 634 v4l2_prio_close(&chan->prio, fh->prio);
694 file->private_data = NULL; 635 file->private_data = NULL;
@@ -765,14 +706,13 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
765{ 706{
766 struct cx25821_channel *chan = video_drvdata(file); 707 struct cx25821_channel *chan = video_drvdata(file);
767 struct cx25821_fh *fh = priv; 708 struct cx25821_fh *fh = priv;
768 struct cx25821_dev *dev = fh->dev;
769 709
770 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 710 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
771 return -EINVAL; 711 return -EINVAL;
772 712
773 if (!cx25821_res_get(dev, fh, 713 if (chan->streaming_fh && chan->streaming_fh != fh)
774 cx25821_get_resource(fh, RESOURCE_VIDEO0)))
775 return -EBUSY; 714 return -EBUSY;
715 chan->streaming_fh = fh;
776 716
777 return videobuf_streamon(&chan->vidq); 717 return videobuf_streamon(&chan->vidq);
778} 718}
@@ -781,18 +721,17 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
781{ 721{
782 struct cx25821_channel *chan = video_drvdata(file); 722 struct cx25821_channel *chan = video_drvdata(file);
783 struct cx25821_fh *fh = priv; 723 struct cx25821_fh *fh = priv;
784 struct cx25821_dev *dev = fh->dev;
785 int err, res;
786 724
787 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 725 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
788 return -EINVAL; 726 return -EINVAL;
789 727
790 res = cx25821_get_resource(fh, RESOURCE_VIDEO0); 728 if (chan->streaming_fh && chan->streaming_fh != fh)
791 err = videobuf_streamoff(&chan->vidq); 729 return -EBUSY;
792 if (err < 0) 730 if (chan->streaming_fh == NULL)
793 return err; 731 return 0;
794 cx25821_res_free(dev, fh, res); 732
795 return 0; 733 chan->streaming_fh = NULL;
734 return videobuf_streamoff(&chan->vidq);
796} 735}
797 736
798static int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm) 737static int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm)
@@ -1483,7 +1422,6 @@ int cx25821_video_register(struct cx25821_dev *dev)
1483 chan->sram_channels->dma_ctl, 0x11, 0); 1422 chan->sram_channels->dma_ctl, 0x11, 0);
1484 1423
1485 chan->sram_channels = &cx25821_sram_channels[i]; 1424 chan->sram_channels = &cx25821_sram_channels[i];
1486 chan->resources = 0;
1487 chan->width = 720; 1425 chan->width = 720;
1488 if (dev->tvnorm & V4L2_STD_625_50) 1426 if (dev->tvnorm & V4L2_STD_625_50)
1489 chan->height = 576; 1427 chan->height = 576;
diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h
index 06dadb5d9e56..128c9f320dfb 100644
--- a/drivers/media/pci/cx25821/cx25821.h
+++ b/drivers/media/pci/cx25821/cx25821.h
@@ -118,7 +118,6 @@ struct cx25821_tvnorm {
118 118
119struct cx25821_fh { 119struct cx25821_fh {
120 struct cx25821_dev *dev; 120 struct cx25821_dev *dev;
121 u32 resources;
122 121
123 enum v4l2_priority prio; 122 enum v4l2_priority prio;
124 123
@@ -208,6 +207,7 @@ struct cx25821_dev;
208struct cx25821_channel { 207struct cx25821_channel {
209 unsigned id; 208 unsigned id;
210 struct cx25821_dev *dev; 209 struct cx25821_dev *dev;
210 struct cx25821_fh *streaming_fh;
211 struct v4l2_prio_state prio; 211 struct v4l2_prio_state prio;
212 212
213 struct v4l2_ctrl_handler hdl; 213 struct v4l2_ctrl_handler hdl;
@@ -219,8 +219,6 @@ struct cx25821_channel {
219 219
220 const struct sram_channel *sram_channels; 220 const struct sram_channel *sram_channels;
221 221
222 int resources;
223
224 const struct cx25821_fmt *fmt; 222 const struct cx25821_fmt *fmt;
225 unsigned int width, height; 223 unsigned int width, height;
226 int pixel_formats; 224 int pixel_formats;
@@ -260,7 +258,6 @@ struct cx25821_dev {
260 char name[32]; 258 char name[32];
261 259
262 /* Analog video */ 260 /* Analog video */
263 u32 resources;
264 unsigned int input; 261 unsigned int input;
265 v4l2_std_id tvnorm; 262 v4l2_std_id tvnorm;
266 unsigned short _max_num_decoders; 263 unsigned short _max_num_decoders;