[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:
Hans Verkuil 2014-08-14 06:43:36 -03:00 committed by Mauro Carvalho Chehab
parent 4d63a25c45
commit f1b6a73532
2 changed files with 17 additions and 8 deletions

View File

@ -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,

View File

@ -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)