[media] cx23885: Add busy checks before changing formats
Before you can change the standard or the capture format, make sure the various vb2_queues aren't in use since you cannot change the buffer size from underneath a a busy vb2_queue. Also make sure that the return code of cx23885_set_tvnorm is returned correctly, otherwise the -EBUSY will be lost. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
This commit is contained in:
parent
4d63a25c45
commit
f1b6a73532
|
@ -1248,18 +1248,18 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
|
||||||
{
|
{
|
||||||
struct cx23885_dev *dev = video_drvdata(file);
|
struct cx23885_dev *dev = video_drvdata(file);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
|
for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
|
||||||
if (id & cx23885_tvnorms[i].id)
|
if (id & cx23885_tvnorms[i].id)
|
||||||
break;
|
break;
|
||||||
if (i == ARRAY_SIZE(cx23885_tvnorms))
|
if (i == ARRAY_SIZE(cx23885_tvnorms))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
dev->encodernorm = cx23885_tvnorms[i];
|
|
||||||
|
|
||||||
/* Have the drier core notify the subdevices */
|
ret = cx23885_set_tvnorm(dev, id);
|
||||||
cx23885_set_tvnorm(dev, id);
|
if (!ret)
|
||||||
|
dev->encodernorm = cx23885_tvnorms[i];
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vidioc_enum_input(struct file *file, void *priv,
|
static int vidioc_enum_input(struct file *file, void *priv,
|
||||||
|
|
|
@ -119,6 +119,12 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
|
||||||
(unsigned int)norm,
|
(unsigned int)norm,
|
||||||
v4l2_norm_to_name(norm));
|
v4l2_norm_to_name(norm));
|
||||||
|
|
||||||
|
if (dev->tvnorm != norm) {
|
||||||
|
if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
|
||||||
|
vb2_is_busy(&dev->vb2_mpegq))
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
dev->tvnorm = norm;
|
dev->tvnorm = norm;
|
||||||
|
|
||||||
call_all(dev, video, s_std, norm);
|
call_all(dev, video, s_std, norm);
|
||||||
|
@ -591,6 +597,11 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
|
||||||
|
|
||||||
if (0 != err)
|
if (0 != err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
|
||||||
|
vb2_is_busy(&dev->vb2_mpegq))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
|
dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
|
||||||
dev->width = f->fmt.pix.width;
|
dev->width = f->fmt.pix.width;
|
||||||
dev->height = f->fmt.pix.height;
|
dev->height = f->fmt.pix.height;
|
||||||
|
@ -654,9 +665,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms)
|
||||||
struct cx23885_dev *dev = video_drvdata(file);
|
struct cx23885_dev *dev = video_drvdata(file);
|
||||||
dprintk(1, "%s()\n", __func__);
|
dprintk(1, "%s()\n", __func__);
|
||||||
|
|
||||||
cx23885_set_tvnorm(dev, tvnorms);
|
return cx23885_set_tvnorm(dev, tvnorms);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
|
int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i)
|
||||||
|
|
Loading…
Reference in New Issue