V4L/DVB: cx231xx: use core-assisted lock
PATCH 1/1 V4L/DVB: cx231xx: use core-assisted lock
Instead of doing its own lock, use core-assisted one. As a bonus, it will do the proper unlock during queue wait events. This fixes a long-standing bug where softwares like tvtime would hang if you try to use cx231xx-alsa.
Signed-off-by Mauro Carvalho Chehab <[email protected]>
drivers/media/video/cx231xx/cx231xx-video.c +8 -78
@@ -1019,8 +1019,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,struct cx231xx_fh *fh = priv;struct cx231xx *dev = fh->dev; -mutex_lock (&dev->lock); - f->fmt.pix.width = dev->width; f->fmt.pix.height = dev->height; f->fmt.pix.pixelformat = dev->format->fourcc;
@@ -1030,8 +1028,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.field =V4L2_FIELD_INTERLACED ; -mutex_unlock (&dev->lock); -return 0 ; }
@@ -1092,26 +1088,20 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,if (rc <0 )return rc; -mutex_lock (&dev->lock); -vidioc_try_fmt_vid_cap (file, priv, f); fmt =format_by_fourcc (f->fmt.pix.pixelformat); -if (!fmt) { - rc = -EINVAL ; - goto out; - } +if (!fmt) +return -EINVAL ;if (videobuf_queue_is_busy (&fh->vb_vidq)) {cx231xx_errdev ("%s queue busy\n" , __func__); - rc = -EBUSY ; - goto out; +return -EBUSY ; }if (dev->stream_on && !fh->stream_on) {cx231xx_errdev ("%s device in use by another fh\n" , __func__); - rc = -EBUSY ; - goto out; +return -EBUSY ; }/* set new image size */
@@ -1123,8 +1113,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,call_all (dev, video, s_mbus_fmt, &mbus_fmt);v4l2_fill_pix_format (&f->fmt.pix, &mbus_fmt); -out: -mutex_unlock (&dev->lock);return rc; }
@@ -1151,7 +1139,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)cx231xx_info ("vidioc_s_std : 0x%x\n" , (unsigned int )*norm); -mutex_lock (&dev->lock); dev->norm = *norm;/* Adjusts width/height, if needed */
@@ -1172,8 +1159,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) dev->width = f.fmt.pix.width; dev->height = f.fmt.pix.height; -mutex_unlock (&dev->lock); -/* do mode control overrides */ cx231xx_do_mode_ctrl_overrides (dev);
@@ -1242,8 +1227,6 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)if (0 ==INPUT (i)->type)return -EINVAL ; -mutex_lock (&dev->lock); -video_mux (dev, i); if (INPUT(i)->type == CX231XX_VMUX_TELEVISION ||
@@ -1254,7 +1237,6 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)call_all (dev, core, s_std, dev->norm); } -mutex_unlock (&dev->lock);return 0 ; }
@@ -1330,9 +1312,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, } *qc = cx231xx_ctls[i].v; -mutex_lock (&dev->lock);call_all (dev, core, queryctrl, qc); -mutex_unlock (&dev->lock);if (qc->type)return 0 ;
@@ -1351,9 +1331,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,if (rc <0 )return rc; -mutex_lock (&dev->lock);call_all (dev, core, g_ctrl, ctrl); -mutex_unlock (&dev->lock);return rc; }
@@ -1368,9 +1346,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,if (rc <0 )return rc; -mutex_lock (&dev->lock);call_all (dev, core, s_ctrl, ctrl); -mutex_unlock (&dev->lock);return rc; }
@@ -1410,9 +1386,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)if (0 != t->index)return -EINVAL ;#if 0 -mutex_lock (&dev->lock);call_all (dev, tuner, s_tuner, t); -mutex_unlock (&dev->lock);#endif return 0 ; }
@@ -1423,14 +1397,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,struct cx231xx_fh *fh = priv;struct cx231xx *dev = fh->dev; -mutex_lock (&dev->lock); f->type = fh->radio ?V4L2_TUNER_RADIO :V4L2_TUNER_ANALOG_TV ; f->frequency = dev->ctl_freq;call_all (dev, tuner, g_frequency, f); -mutex_unlock (&dev->lock); -return 0 ; }
@@ -1461,13 +1432,9 @@ static int vidioc_s_frequency(struct file *file, void *priv,/* set pre channel change settings in DIF first */ rc =cx231xx_tuner_pre_channel_change (dev); -mutex_lock (&dev->lock); - dev->ctl_freq = f->frequency;call_all (dev, tuner, s_frequency, f); -mutex_unlock (&dev->lock); -/* set post channel change settings in DIF first */ rc =cx231xx_tuner_post_channel_change (dev);
@@ -1655,9 +1622,7 @@ static int vidioc_g_register(struct file *file, void *priv,return -EINVAL ; } -mutex_lock (&dev->lock);call_all (dev, core, g_register, reg); -mutex_unlock (&dev->lock);return ret; }
@@ -1822,9 +1787,7 @@ static int vidioc_s_register(struct file *file, void *priv,break ; } -mutex_lock (&dev->lock);call_all (dev, core, s_register, reg); -mutex_unlock (&dev->lock);return ret; }
@@ -1861,7 +1824,6 @@ static int vidioc_streamon(struct file *file, void *priv,if (rc <0 )return rc; -mutex_lock (&dev->lock); rc =res_get (fh);if (likely (rc >=0 ))
@@ -1869,8 +1831,6 @@ static int vidioc_streamon(struct file *file, void *priv,call_all (dev, video, s_stream,1 ); -mutex_unlock (&dev->lock); -return rc; }
@@ -1891,15 +1851,11 @@ static int vidioc_streamoff(struct file *file, void *priv,if (type != fh->type)return -EINVAL ; -mutex_lock (&dev->lock); -cx25840_call (dev, video, s_stream,0 );videobuf_streamoff (&fh->vb_vidq);res_free (fh); -mutex_unlock (&dev->lock); -return 0 ; }
@@ -1954,8 +1910,6 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,if (rc <0 )return rc; -mutex_lock (&dev->lock); - f->fmt.sliced.service_set =0 ;call_all (dev, vbi, g_sliced_fmt, &f->fmt.sliced);
@@ -1963,7 +1917,6 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,if (f->fmt.sliced.service_set ==0 ) rc = -EINVAL ; -mutex_unlock (&dev->lock);return rc; }
@@ -1978,9 +1931,7 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,if (rc <0 )return rc; -mutex_lock (&dev->lock);call_all (dev, vbi, g_sliced_fmt, &f->fmt.sliced); -mutex_unlock (&dev->lock);if (f->fmt.sliced.service_set ==0 )return -EINVAL ;
@@ -2130,9 +2081,7 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)strcpy (t->name,"Radio" ); t->type =V4L2_TUNER_RADIO ; -mutex_lock (&dev->lock);call_all (dev, tuner, s_tuner, t); -mutex_unlock (&dev->lock);return 0 ; }
@@ -2163,9 +2112,7 @@ static int radio_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)if (0 != t->index)return -EINVAL ; -mutex_lock (&dev->lock);call_all (dev, tuner, s_tuner, t); -mutex_unlock (&dev->lock);return 0 ; }
@@ -2224,8 +2171,6 @@ static int cx231xx_v4l2_open(struct file *filp)break ; } -mutex_lock (&dev->lock); -cx231xx_videodbg ("open dev=%s type=%s users=%d\n" ,video_device_node_name (vdev), v4l2_type_names[fh_type], dev->users);
@@ -2235,7 +2180,6 @@ static int cx231xx_v4l2_open(struct file *filp)if (errCode <0 ) {cx231xx_errdev ("Device locked on digital mode. Can't open analog\n" ); -mutex_unlock (&dev->lock);return -EBUSY ; }#endif
@@ -2243,7 +2187,6 @@ static int cx231xx_v4l2_open(struct file *filp) fh =kzalloc (sizeof (struct cx231xx_fh ),GFP_KERNEL );if (!fh) {cx231xx_errdev ("cx231xx-video.c: Out of memory?!\n" ); -mutex_unlock (&dev->lock);return -ENOMEM ; } fh->dev = dev;
@@ -2293,7 +2236,7 @@ static int cx231xx_v4l2_open(struct file *filp)NULL , &dev->video_mode.slock, fh->type,V4L2_FIELD_INTERLACED ,sizeof (struct cx231xx_buffer ), - fh, NULL); + fh, &dev->lock);if (fh->type ==V4L2_BUF_TYPE_VBI_CAPTURE ) {/* Set the required alternate setting VBI interface works in Bulk mode only */
@@ -2305,11 +2248,9 @@ static int cx231xx_v4l2_open(struct file *filp)NULL , &dev->vbi_mode.slock, fh->type,V4L2_FIELD_SEQ_TB ,sizeof (struct cx231xx_buffer ), - fh, NULL); + fh, &dev->lock); } -mutex_unlock (&dev->lock); -return errCode; }
@@ -2366,7 +2307,6 @@ static int cx231xx_v4l2_close(struct file *filp)cx231xx_videodbg ("users=%d\n" , dev->users); -mutex_lock (&dev->lock);cx231xx_videodbg ("users=%d\n" , dev->users);if (res_check (fh))res_free (fh);
@@ -2384,12 +2324,10 @@ static int cx231xx_v4l2_close(struct file *filp)if (dev->state &DEV_DISCONNECTED ) {if (atomic_read (&dev->devlist_count) >0 ) {cx231xx_release_resources (dev); -mutex_unlock (&dev->lock);kfree (dev); dev =NULL ;return 0 ; } -mutex_unlock (&dev->lock);return 0 ; }
@@ -2405,7 +2343,6 @@ static int cx231xx_v4l2_close(struct file *filp)kfree (fh); dev->users--;wake_up_interruptible_nr (&dev->open,1 ); -mutex_unlock (&dev->lock);return 0 ; }
@@ -2417,7 +2354,6 @@ static int cx231xx_v4l2_close(struct file *filp)free the remaining resources */ if (dev->state &DEV_DISCONNECTED ) {cx231xx_release_resources (dev); -mutex_unlock (&dev->lock);kfree (dev); dev =NULL ;return 0 ;
@@ -2439,7 +2375,6 @@ static int cx231xx_v4l2_close(struct file *filp)kfree (fh); dev->users--;wake_up_interruptible_nr (&dev->open,1 ); -mutex_unlock (&dev->lock);return 0 ; }
@@ -2461,9 +2396,7 @@ cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count,if ((fh->type ==V4L2_BUF_TYPE_VIDEO_CAPTURE ) || (fh->type ==V4L2_BUF_TYPE_VBI_CAPTURE )) { -mutex_lock (&dev->lock); rc =res_get (fh); -mutex_unlock (&dev->lock);if (unlikely (rc <0 ))return rc;
@@ -2488,9 +2421,7 @@ static unsigned int cx231xx_v4l2_poll(struct file *filp, poll_table *wait)if (rc <0 )return rc; -mutex_lock (&dev->lock); rc =res_get (fh); -mutex_unlock (&dev->lock);if (unlikely (rc <0 ))return POLLERR ;
@@ -2515,9 +2446,7 @@ static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)if (rc <0 )return rc; -mutex_lock (&dev->lock); rc =res_get (fh); -mutex_unlock (&dev->lock);if (unlikely (rc <0 ))return rc;
@@ -2539,7 +2468,7 @@ static const struct v4l2_file_operations cx231xx_v4l_fops = { .read = cx231xx_v4l2_read, .poll = cx231xx_v4l2_poll, .mmap = cx231xx_v4l2_mmap, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, };static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -2641,6 +2570,7 @@ static struct video_device *cx231xx_vdev_init(struct cx231xx *dev, vfd->v4l2_dev = &dev->v4l2_dev; vfd->release = video_device_release; vfd->debug = video_debug; + vfd->lock = &dev->lock;snprintf (vfd->name,sizeof (vfd->name),"%s %s" , dev->name, type_name);
Signature · 1 line
1.7.1