aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2011-10-11 05:06:58 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-01-16 06:59:43 -0500
commitcdc037817cc15caf931cd3476970860d62f1985c (patch)
treef6694311b9bcc8d0f58d4f20ca46d6ce49eb54c0 /drivers/media
parent4d68e700d6a192a5a8b394b26ac056a1c0fa6ebc (diff)
[media] ivtv: switch to the v4l core lock
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Andy Walls <awalls@md.metrocast.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c48
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c22
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c22
4 files changed, 39 insertions, 54 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 69a3de9bae62..116ece4d6f27 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -268,11 +268,13 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block,
268 } 268 }
269 269
270 /* wait for more data to arrive */ 270 /* wait for more data to arrive */
271 mutex_unlock(&itv->serialize_lock);
271 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); 272 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
272 /* New buffers might have become available before we were added to the waitqueue */ 273 /* New buffers might have become available before we were added to the waitqueue */
273 if (!s->q_full.buffers) 274 if (!s->q_full.buffers)
274 schedule(); 275 schedule();
275 finish_wait(&s->waitq, &wait); 276 finish_wait(&s->waitq, &wait);
277 mutex_lock(&itv->serialize_lock);
276 if (signal_pending(current)) { 278 if (signal_pending(current)) {
277 /* return if a signal was received */ 279 /* return if a signal was received */
278 IVTV_DEBUG_INFO("User stopped %s\n", s->name); 280 IVTV_DEBUG_INFO("User stopped %s\n", s->name);
@@ -507,9 +509,7 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_
507 509
508 IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); 510 IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
509 511
510 mutex_lock(&itv->serialize_lock);
511 rc = ivtv_start_capture(id); 512 rc = ivtv_start_capture(id);
512 mutex_unlock(&itv->serialize_lock);
513 if (rc) 513 if (rc)
514 return rc; 514 return rc;
515 return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); 515 return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
@@ -584,9 +584,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
584 set_bit(IVTV_F_S_APPL_IO, &s->s_flags); 584 set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
585 585
586 /* Start decoder (returns 0 if already started) */ 586 /* Start decoder (returns 0 if already started) */
587 mutex_lock(&itv->serialize_lock);
588 rc = ivtv_start_decoding(id, itv->speed); 587 rc = ivtv_start_decoding(id, itv->speed);
589 mutex_unlock(&itv->serialize_lock);
590 if (rc) { 588 if (rc) {
591 IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); 589 IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
592 590
@@ -627,11 +625,13 @@ retry:
627 break; 625 break;
628 if (filp->f_flags & O_NONBLOCK) 626 if (filp->f_flags & O_NONBLOCK)
629 return -EAGAIN; 627 return -EAGAIN;
628 mutex_unlock(&itv->serialize_lock);
630 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); 629 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
631 /* New buffers might have become free before we were added to the waitqueue */ 630 /* New buffers might have become free before we were added to the waitqueue */
632 if (!s->q_free.buffers) 631 if (!s->q_free.buffers)
633 schedule(); 632 schedule();
634 finish_wait(&s->waitq, &wait); 633 finish_wait(&s->waitq, &wait);
634 mutex_lock(&itv->serialize_lock);
635 if (signal_pending(current)) { 635 if (signal_pending(current)) {
636 IVTV_DEBUG_INFO("User stopped %s\n", s->name); 636 IVTV_DEBUG_INFO("User stopped %s\n", s->name);
637 return -EINTR; 637 return -EINTR;
@@ -686,12 +686,14 @@ retry:
686 if (mode == OUT_YUV) 686 if (mode == OUT_YUV)
687 ivtv_yuv_setup_stream_frame(itv); 687 ivtv_yuv_setup_stream_frame(itv);
688 688
689 mutex_unlock(&itv->serialize_lock);
689 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); 690 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
690 while (!(got_sig = signal_pending(current)) && 691 while (!(got_sig = signal_pending(current)) &&
691 test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) { 692 test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) {
692 schedule(); 693 schedule();
693 } 694 }
694 finish_wait(&itv->dma_waitq, &wait); 695 finish_wait(&itv->dma_waitq, &wait);
696 mutex_lock(&itv->serialize_lock);
695 if (got_sig) { 697 if (got_sig) {
696 IVTV_DEBUG_INFO("User interrupted %s\n", s->name); 698 IVTV_DEBUG_INFO("User interrupted %s\n", s->name);
697 return -EINTR; 699 return -EINTR;
@@ -756,9 +758,7 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
756 if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { 758 if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
757 int rc; 759 int rc;
758 760
759 mutex_lock(&itv->serialize_lock);
760 rc = ivtv_start_capture(id); 761 rc = ivtv_start_capture(id);
761 mutex_unlock(&itv->serialize_lock);
762 if (rc) { 762 if (rc) {
763 IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", 763 IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n",
764 s->name, rc); 764 s->name, rc);
@@ -861,7 +861,6 @@ int ivtv_v4l2_close(struct file *filp)
861 861
862 IVTV_DEBUG_FILE("close %s\n", s->name); 862 IVTV_DEBUG_FILE("close %s\n", s->name);
863 863
864 mutex_lock(&itv->serialize_lock);
865 /* Stop radio */ 864 /* Stop radio */
866 if (id->type == IVTV_ENC_STREAM_TYPE_RAD && 865 if (id->type == IVTV_ENC_STREAM_TYPE_RAD &&
867 v4l2_fh_is_singular_file(filp)) { 866 v4l2_fh_is_singular_file(filp)) {
@@ -893,7 +892,6 @@ int ivtv_v4l2_close(struct file *filp)
893 /* Easy case first: this stream was never claimed by us */ 892 /* Easy case first: this stream was never claimed by us */
894 if (s->id != id->open_id) { 893 if (s->id != id->open_id) {
895 kfree(id); 894 kfree(id);
896 mutex_unlock(&itv->serialize_lock);
897 return 0; 895 return 0;
898 } 896 }
899 897
@@ -914,21 +912,25 @@ int ivtv_v4l2_close(struct file *filp)
914 ivtv_stop_capture(id, 0); 912 ivtv_stop_capture(id, 0);
915 } 913 }
916 kfree(id); 914 kfree(id);
917 mutex_unlock(&itv->serialize_lock);
918 return 0; 915 return 0;
919} 916}
920 917
921static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) 918int ivtv_v4l2_open(struct file *filp)
922{ 919{
923#ifdef CONFIG_VIDEO_ADV_DEBUG
924 struct video_device *vdev = video_devdata(filp); 920 struct video_device *vdev = video_devdata(filp);
925#endif 921 struct ivtv_stream *s = video_get_drvdata(vdev);
926 struct ivtv *itv = s->itv; 922 struct ivtv *itv = s->itv;
927 struct ivtv_open_id *item; 923 struct ivtv_open_id *item;
928 int res = 0; 924 int res = 0;
929 925
930 IVTV_DEBUG_FILE("open %s\n", s->name); 926 IVTV_DEBUG_FILE("open %s\n", s->name);
931 927
928 if (ivtv_init_on_first_open(itv)) {
929 IVTV_ERR("Failed to initialize on device %s\n",
930 video_device_node_name(vdev));
931 return -ENXIO;
932 }
933
932#ifdef CONFIG_VIDEO_ADV_DEBUG 934#ifdef CONFIG_VIDEO_ADV_DEBUG
933 /* Unless ivtv_fw_debug is set, error out if firmware dead. */ 935 /* Unless ivtv_fw_debug is set, error out if firmware dead. */
934 if (ivtv_fw_debug) { 936 if (ivtv_fw_debug) {
@@ -1017,28 +1019,6 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
1017 return 0; 1019 return 0;
1018} 1020}
1019 1021
1020int ivtv_v4l2_open(struct file *filp)
1021{
1022 int res;
1023 struct ivtv *itv = NULL;
1024 struct ivtv_stream *s = NULL;
1025 struct video_device *vdev = video_devdata(filp);
1026
1027 s = video_get_drvdata(vdev);
1028 itv = s->itv;
1029
1030 mutex_lock(&itv->serialize_lock);
1031 if (ivtv_init_on_first_open(itv)) {
1032 IVTV_ERR("Failed to initialize on device %s\n",
1033 video_device_node_name(vdev));
1034 mutex_unlock(&itv->serialize_lock);
1035 return -ENXIO;
1036 }
1037 res = ivtv_serialized_open(s, filp);
1038 mutex_unlock(&itv->serialize_lock);
1039 return res;
1040}
1041
1042void ivtv_mute(struct ivtv *itv) 1022void ivtv_mute(struct ivtv *itv)
1043{ 1023{
1044 if (atomic_read(&itv->capturing)) 1024 if (atomic_read(&itv->capturing))
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index ecafa697326e..c4bc48143098 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -179,6 +179,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed)
179 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0); 179 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
180 180
181 /* Wait for any DMA to finish */ 181 /* Wait for any DMA to finish */
182 mutex_unlock(&itv->serialize_lock);
182 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); 183 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
183 while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) { 184 while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
184 got_sig = signal_pending(current); 185 got_sig = signal_pending(current);
@@ -188,6 +189,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed)
188 schedule(); 189 schedule();
189 } 190 }
190 finish_wait(&itv->dma_waitq, &wait); 191 finish_wait(&itv->dma_waitq, &wait);
192 mutex_lock(&itv->serialize_lock);
191 if (got_sig) 193 if (got_sig)
192 return -EINTR; 194 return -EINTR;
193 195
@@ -1107,6 +1109,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
1107 * happens within the first 100 lines of the top field. 1109 * happens within the first 100 lines of the top field.
1108 * Make 4 attempts to sync to the decoder before giving up. 1110 * Make 4 attempts to sync to the decoder before giving up.
1109 */ 1111 */
1112 mutex_unlock(&itv->serialize_lock);
1110 for (f = 0; f < 4; f++) { 1113 for (f = 0; f < 4; f++) {
1111 prepare_to_wait(&itv->vsync_waitq, &wait, 1114 prepare_to_wait(&itv->vsync_waitq, &wait,
1112 TASK_UNINTERRUPTIBLE); 1115 TASK_UNINTERRUPTIBLE);
@@ -1115,6 +1118,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
1115 schedule_timeout(msecs_to_jiffies(25)); 1118 schedule_timeout(msecs_to_jiffies(25));
1116 } 1119 }
1117 finish_wait(&itv->vsync_waitq, &wait); 1120 finish_wait(&itv->vsync_waitq, &wait);
1121 mutex_lock(&itv->serialize_lock);
1118 1122
1119 if (f == 4) 1123 if (f == 4)
1120 IVTV_WARN("Mode change failed to sync to decoder\n"); 1124 IVTV_WARN("Mode change failed to sync to decoder\n");
@@ -1842,8 +1846,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1842 return 0; 1846 return 0;
1843} 1847}
1844 1848
1845static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, 1849long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1846 unsigned int cmd, unsigned long arg)
1847{ 1850{
1848 struct video_device *vfd = video_devdata(filp); 1851 struct video_device *vfd = video_devdata(filp);
1849 long ret; 1852 long ret;
@@ -1855,21 +1858,6 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
1855 return ret; 1858 return ret;
1856} 1859}
1857 1860
1858long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1859{
1860 struct ivtv_open_id *id = fh2id(filp->private_data);
1861 struct ivtv *itv = id->itv;
1862 long res;
1863
1864 /* DQEVENT can block, so this should not run with the serialize lock */
1865 if (cmd == VIDIOC_DQEVENT)
1866 return ivtv_serialized_ioctl(itv, filp, cmd, arg);
1867 mutex_lock(&itv->serialize_lock);
1868 res = ivtv_serialized_ioctl(itv, filp, cmd, arg);
1869 mutex_unlock(&itv->serialize_lock);
1870 return res;
1871}
1872
1873static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { 1861static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1874 .vidioc_querycap = ivtv_querycap, 1862 .vidioc_querycap = ivtv_querycap,
1875 .vidioc_s_audio = ivtv_s_audio, 1863 .vidioc_s_audio = ivtv_s_audio,
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index e7794dc1330e..d598df046605 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -214,6 +214,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
214 s->vdev->fops = ivtv_stream_info[type].fops; 214 s->vdev->fops = ivtv_stream_info[type].fops;
215 s->vdev->release = video_device_release; 215 s->vdev->release = video_device_release;
216 s->vdev->tvnorms = V4L2_STD_ALL; 216 s->vdev->tvnorms = V4L2_STD_ALL;
217 s->vdev->lock = &itv->serialize_lock;
217 set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags); 218 set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
218 ivtv_set_funcs(s->vdev); 219 ivtv_set_funcs(s->vdev);
219 return 0; 220 return 0;
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index dcbab6ad4c26..2ad65eb29832 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -1149,23 +1149,37 @@ int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src)
1149{ 1149{
1150 struct yuv_playback_info *yi = &itv->yuv_info; 1150 struct yuv_playback_info *yi = &itv->yuv_info;
1151 struct ivtv_dma_frame dma_args; 1151 struct ivtv_dma_frame dma_args;
1152 int res;
1152 1153
1153 ivtv_yuv_setup_stream_frame(itv); 1154 ivtv_yuv_setup_stream_frame(itv);
1154 1155
1155 /* We only need to supply source addresses for this */ 1156 /* We only need to supply source addresses for this */
1156 dma_args.y_source = src; 1157 dma_args.y_source = src;
1157 dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31); 1158 dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31);
1158 return ivtv_yuv_udma_frame(itv, &dma_args); 1159 /* Wait for frame DMA. Note that serialize_lock is locked,
1160 so to allow other processes to access the driver while
1161 we are waiting unlock first and later lock again. */
1162 mutex_unlock(&itv->serialize_lock);
1163 res = ivtv_yuv_udma_frame(itv, &dma_args);
1164 mutex_lock(&itv->serialize_lock);
1165 return res;
1159} 1166}
1160 1167
1161/* IVTV_IOC_DMA_FRAME ioctl handler */ 1168/* IVTV_IOC_DMA_FRAME ioctl handler */
1162int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) 1169int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1163{ 1170{
1164/* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */ 1171 int res;
1165 1172
1173/* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */
1166 ivtv_yuv_next_free(itv); 1174 ivtv_yuv_next_free(itv);
1167 ivtv_yuv_setup_frame(itv, args); 1175 ivtv_yuv_setup_frame(itv, args);
1168 return ivtv_yuv_udma_frame(itv, args); 1176 /* Wait for frame DMA. Note that serialize_lock is locked,
1177 so to allow other processes to access the driver while
1178 we are waiting unlock first and later lock again. */
1179 mutex_unlock(&itv->serialize_lock);
1180 res = ivtv_yuv_udma_frame(itv, args);
1181 mutex_lock(&itv->serialize_lock);
1182 return res;
1169} 1183}
1170 1184
1171void ivtv_yuv_close(struct ivtv *itv) 1185void ivtv_yuv_close(struct ivtv *itv)
@@ -1174,7 +1188,9 @@ void ivtv_yuv_close(struct ivtv *itv)
1174 int h_filter, v_filter_1, v_filter_2; 1188 int h_filter, v_filter_1, v_filter_2;
1175 1189
1176 IVTV_DEBUG_YUV("ivtv_yuv_close\n"); 1190 IVTV_DEBUG_YUV("ivtv_yuv_close\n");
1191 mutex_unlock(&itv->serialize_lock);
1177 ivtv_waitq(&itv->vsync_waitq); 1192 ivtv_waitq(&itv->vsync_waitq);
1193 mutex_lock(&itv->serialize_lock);
1178 1194
1179 yi->running = 0; 1195 yi->running = 0;
1180 atomic_set(&yi->next_dma_frame, -1); 1196 atomic_set(&yi->next_dma_frame, -1);