diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-04-14 10:56:39 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-04-16 17:07:13 -0400 |
commit | 84293f0843931b13d8331093bafacd1d70dd5efb (patch) | |
tree | 5cc43ab7d463a478578c4ed89933013bb4a02247 /drivers/media | |
parent | 2efe2cc4305ad9a8ea4db5881808c4db1c451091 (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.c | 130 | ||||
-rw-r--r-- | drivers/media/pci/cx25821/cx25821.h | 5 |
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 */ | ||
148 | static 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 | |||
168 | static int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit) | ||
169 | { | ||
170 | return fh->resources & bit; | ||
171 | } | ||
172 | |||
173 | static int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit) | ||
174 | { | ||
175 | return fh->dev->channels[fh->channel_id].resources & bit; | ||
176 | } | ||
177 | |||
178 | static 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 | |||
189 | static int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input) | 147 | static 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 | ||
506 | static int cx25821_get_resource(struct cx25821_fh *fh, int resource) | ||
507 | { | ||
508 | return resource; | ||
509 | } | ||
510 | |||
511 | static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma) | 464 | static 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); |
579 | unlock: | ||
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, | |||
627 | static unsigned int video_poll(struct file *file, | 584 | static 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 | ||
667 | static int video_release(struct file *file) | 608 | static 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 | ||
798 | static int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm) | 737 | static 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 | ||
119 | struct cx25821_fh { | 119 | struct 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; | |||
208 | struct cx25821_channel { | 207 | struct 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; |