aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2010-08-17 13:29:51 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-20 23:06:18 -0400
commit57bee29d6e8cf721864fa47a18366bee5ff24f21 (patch)
treeeec0e9a15386db2bbe041f9e39d60075614c5adc
parent79c6ff93c74e793ccceb464ee3698478c812ce79 (diff)
V4L/DVB: soc-camera: allow only one video queue per device
Multiple user-space application instances can open the same video device, but it only makes sense for one of them to manage the videobuffer queue and set video format of the device. Restrict soc-camera respectively. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/mx1_camera.c8
-rw-r--r--drivers/media/video/mx3_camera.c6
-rw-r--r--drivers/media/video/pxa_camera.c8
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c8
-rw-r--r--drivers/media/video/soc_camera.c178
-rw-r--r--include/media/soc_camera.h9
6 files changed, 107 insertions, 110 deletions
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index e8a5ffcb6f06..adc72c4a9f08 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -638,7 +638,7 @@ static int mx1_camera_try_fmt(struct soc_camera_device *icd,
638 return 0; 638 return 0;
639} 639}
640 640
641static int mx1_camera_reqbufs(struct soc_camera_file *icf, 641static int mx1_camera_reqbufs(struct soc_camera_device *icd,
642 struct v4l2_requestbuffers *p) 642 struct v4l2_requestbuffers *p)
643{ 643{
644 int i; 644 int i;
@@ -650,7 +650,7 @@ static int mx1_camera_reqbufs(struct soc_camera_file *icf,
650 * it hadn't triggered 650 * it hadn't triggered
651 */ 651 */
652 for (i = 0; i < p->count; i++) { 652 for (i = 0; i < p->count; i++) {
653 struct mx1_buffer *buf = container_of(icf->vb_vidq.bufs[i], 653 struct mx1_buffer *buf = container_of(icd->vb_vidq.bufs[i],
654 struct mx1_buffer, vb); 654 struct mx1_buffer, vb);
655 buf->inwork = 0; 655 buf->inwork = 0;
656 INIT_LIST_HEAD(&buf->vb.queue); 656 INIT_LIST_HEAD(&buf->vb.queue);
@@ -661,10 +661,10 @@ static int mx1_camera_reqbufs(struct soc_camera_file *icf,
661 661
662static unsigned int mx1_camera_poll(struct file *file, poll_table *pt) 662static unsigned int mx1_camera_poll(struct file *file, poll_table *pt)
663{ 663{
664 struct soc_camera_file *icf = file->private_data; 664 struct soc_camera_device *icd = file->private_data;
665 struct mx1_buffer *buf; 665 struct mx1_buffer *buf;
666 666
667 buf = list_entry(icf->vb_vidq.stream.next, struct mx1_buffer, 667 buf = list_entry(icd->vb_vidq.stream.next, struct mx1_buffer,
668 vb.stream); 668 vb.stream);
669 669
670 poll_wait(file, &buf->vb.done, pt); 670 poll_wait(file, &buf->vb.done, pt);
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index a13076969e5a..d020388d29ca 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -976,7 +976,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
976 return ret; 976 return ret;
977} 977}
978 978
979static int mx3_camera_reqbufs(struct soc_camera_file *icf, 979static int mx3_camera_reqbufs(struct soc_camera_device *icd,
980 struct v4l2_requestbuffers *p) 980 struct v4l2_requestbuffers *p)
981{ 981{
982 return 0; 982 return 0;
@@ -984,9 +984,9 @@ static int mx3_camera_reqbufs(struct soc_camera_file *icf,
984 984
985static unsigned int mx3_camera_poll(struct file *file, poll_table *pt) 985static unsigned int mx3_camera_poll(struct file *file, poll_table *pt)
986{ 986{
987 struct soc_camera_file *icf = file->private_data; 987 struct soc_camera_device *icd = file->private_data;
988 988
989 return videobuf_poll_stream(file, &icf->vb_vidq, pt); 989 return videobuf_poll_stream(file, &icd->vb_vidq, pt);
990} 990}
991 991
992static int mx3_camera_querycap(struct soc_camera_host *ici, 992static int mx3_camera_querycap(struct soc_camera_host *ici,
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 109ba99ae121..7ffa525019d4 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -1539,7 +1539,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1539 return ret; 1539 return ret;
1540} 1540}
1541 1541
1542static int pxa_camera_reqbufs(struct soc_camera_file *icf, 1542static int pxa_camera_reqbufs(struct soc_camera_device *icd,
1543 struct v4l2_requestbuffers *p) 1543 struct v4l2_requestbuffers *p)
1544{ 1544{
1545 int i; 1545 int i;
@@ -1551,7 +1551,7 @@ static int pxa_camera_reqbufs(struct soc_camera_file *icf,
1551 * it hadn't triggered 1551 * it hadn't triggered
1552 */ 1552 */
1553 for (i = 0; i < p->count; i++) { 1553 for (i = 0; i < p->count; i++) {
1554 struct pxa_buffer *buf = container_of(icf->vb_vidq.bufs[i], 1554 struct pxa_buffer *buf = container_of(icd->vb_vidq.bufs[i],
1555 struct pxa_buffer, vb); 1555 struct pxa_buffer, vb);
1556 buf->inwork = 0; 1556 buf->inwork = 0;
1557 INIT_LIST_HEAD(&buf->vb.queue); 1557 INIT_LIST_HEAD(&buf->vb.queue);
@@ -1562,10 +1562,10 @@ static int pxa_camera_reqbufs(struct soc_camera_file *icf,
1562 1562
1563static unsigned int pxa_camera_poll(struct file *file, poll_table *pt) 1563static unsigned int pxa_camera_poll(struct file *file, poll_table *pt)
1564{ 1564{
1565 struct soc_camera_file *icf = file->private_data; 1565 struct soc_camera_device *icd = file->private_data;
1566 struct pxa_buffer *buf; 1566 struct pxa_buffer *buf;
1567 1567
1568 buf = list_entry(icf->vb_vidq.stream.next, struct pxa_buffer, 1568 buf = list_entry(icd->vb_vidq.stream.next, struct pxa_buffer,
1569 vb.stream); 1569 vb.stream);
1570 1570
1571 poll_wait(file, &buf->vb.done, pt); 1571 poll_wait(file, &buf->vb.done, pt);
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 39211628d427..cbc997d591bf 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -1726,7 +1726,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1726 return ret; 1726 return ret;
1727} 1727}
1728 1728
1729static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf, 1729static int sh_mobile_ceu_reqbufs(struct soc_camera_device *icd,
1730 struct v4l2_requestbuffers *p) 1730 struct v4l2_requestbuffers *p)
1731{ 1731{
1732 int i; 1732 int i;
@@ -1740,7 +1740,7 @@ static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf,
1740 for (i = 0; i < p->count; i++) { 1740 for (i = 0; i < p->count; i++) {
1741 struct sh_mobile_ceu_buffer *buf; 1741 struct sh_mobile_ceu_buffer *buf;
1742 1742
1743 buf = container_of(icf->vb_vidq.bufs[i], 1743 buf = container_of(icd->vb_vidq.bufs[i],
1744 struct sh_mobile_ceu_buffer, vb); 1744 struct sh_mobile_ceu_buffer, vb);
1745 INIT_LIST_HEAD(&buf->vb.queue); 1745 INIT_LIST_HEAD(&buf->vb.queue);
1746 } 1746 }
@@ -1750,10 +1750,10 @@ static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf,
1750 1750
1751static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt) 1751static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
1752{ 1752{
1753 struct soc_camera_file *icf = file->private_data; 1753 struct soc_camera_device *icd = file->private_data;
1754 struct sh_mobile_ceu_buffer *buf; 1754 struct sh_mobile_ceu_buffer *buf;
1755 1755
1756 buf = list_entry(icf->vb_vidq.stream.next, 1756 buf = list_entry(icd->vb_vidq.stream.next,
1757 struct sh_mobile_ceu_buffer, vb.stream); 1757 struct sh_mobile_ceu_buffer, vb.stream);
1758 1758
1759 poll_wait(file, &buf->vb.done, pt); 1759 poll_wait(file, &buf->vb.done, pt);
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index a55d6dc4c6bd..6876fdcbf8d7 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -92,8 +92,7 @@ EXPORT_SYMBOL(soc_camera_apply_sensor_flags);
92static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, 92static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
93 struct v4l2_format *f) 93 struct v4l2_format *f)
94{ 94{
95 struct soc_camera_file *icf = file->private_data; 95 struct soc_camera_device *icd = file->private_data;
96 struct soc_camera_device *icd = icf->icd;
97 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 96 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
98 97
99 WARN_ON(priv != file->private_data); 98 WARN_ON(priv != file->private_data);
@@ -105,8 +104,7 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
105static int soc_camera_enum_input(struct file *file, void *priv, 104static int soc_camera_enum_input(struct file *file, void *priv,
106 struct v4l2_input *inp) 105 struct v4l2_input *inp)
107{ 106{
108 struct soc_camera_file *icf = file->private_data; 107 struct soc_camera_device *icd = file->private_data;
109 struct soc_camera_device *icd = icf->icd;
110 int ret = 0; 108 int ret = 0;
111 109
112 if (inp->index != 0) 110 if (inp->index != 0)
@@ -141,8 +139,7 @@ static int soc_camera_s_input(struct file *file, void *priv, unsigned int i)
141 139
142static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a) 140static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
143{ 141{
144 struct soc_camera_file *icf = file->private_data; 142 struct soc_camera_device *icd = file->private_data;
145 struct soc_camera_device *icd = icf->icd;
146 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 143 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
147 144
148 return v4l2_subdev_call(sd, core, s_std, *a); 145 return v4l2_subdev_call(sd, core, s_std, *a);
@@ -152,47 +149,59 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
152 struct v4l2_requestbuffers *p) 149 struct v4l2_requestbuffers *p)
153{ 150{
154 int ret; 151 int ret;
155 struct soc_camera_file *icf = file->private_data; 152 struct soc_camera_device *icd = file->private_data;
156 struct soc_camera_device *icd = icf->icd;
157 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 153 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
158 154
159 WARN_ON(priv != file->private_data); 155 WARN_ON(priv != file->private_data);
160 156
161 ret = videobuf_reqbufs(&icf->vb_vidq, p); 157 if (icd->streamer && icd->streamer != file)
158 return -EBUSY;
159
160 ret = videobuf_reqbufs(&icd->vb_vidq, p);
162 if (ret < 0) 161 if (ret < 0)
163 return ret; 162 return ret;
164 163
165 return ici->ops->reqbufs(icf, p); 164 ret = ici->ops->reqbufs(icd, p);
165 if (!ret && !icd->streamer)
166 icd->streamer = file;
167
168 return ret;
166} 169}
167 170
168static int soc_camera_querybuf(struct file *file, void *priv, 171static int soc_camera_querybuf(struct file *file, void *priv,
169 struct v4l2_buffer *p) 172 struct v4l2_buffer *p)
170{ 173{
171 struct soc_camera_file *icf = file->private_data; 174 struct soc_camera_device *icd = file->private_data;
172 175
173 WARN_ON(priv != file->private_data); 176 WARN_ON(priv != file->private_data);
174 177
175 return videobuf_querybuf(&icf->vb_vidq, p); 178 return videobuf_querybuf(&icd->vb_vidq, p);
176} 179}
177 180
178static int soc_camera_qbuf(struct file *file, void *priv, 181static int soc_camera_qbuf(struct file *file, void *priv,
179 struct v4l2_buffer *p) 182 struct v4l2_buffer *p)
180{ 183{
181 struct soc_camera_file *icf = file->private_data; 184 struct soc_camera_device *icd = file->private_data;
182 185
183 WARN_ON(priv != file->private_data); 186 WARN_ON(priv != file->private_data);
184 187
185 return videobuf_qbuf(&icf->vb_vidq, p); 188 if (icd->streamer != file)
189 return -EBUSY;
190
191 return videobuf_qbuf(&icd->vb_vidq, p);
186} 192}
187 193
188static int soc_camera_dqbuf(struct file *file, void *priv, 194static int soc_camera_dqbuf(struct file *file, void *priv,
189 struct v4l2_buffer *p) 195 struct v4l2_buffer *p)
190{ 196{
191 struct soc_camera_file *icf = file->private_data; 197 struct soc_camera_device *icd = file->private_data;
192 198
193 WARN_ON(priv != file->private_data); 199 WARN_ON(priv != file->private_data);
194 200
195 return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK); 201 if (icd->streamer != file)
202 return -EBUSY;
203
204 return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK);
196} 205}
197 206
198/* Always entered with .video_lock held */ 207/* Always entered with .video_lock held */
@@ -280,10 +289,9 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd)
280 ((x) >> 24) & 0xff 289 ((x) >> 24) & 0xff
281 290
282/* Called with .vb_lock held, or from the first open(2), see comment there */ 291/* Called with .vb_lock held, or from the first open(2), see comment there */
283static int soc_camera_set_fmt(struct soc_camera_file *icf, 292static int soc_camera_set_fmt(struct soc_camera_device *icd,
284 struct v4l2_format *f) 293 struct v4l2_format *f)
285{ 294{
286 struct soc_camera_device *icd = icf->icd;
287 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 295 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
288 struct v4l2_pix_format *pix = &f->fmt.pix; 296 struct v4l2_pix_format *pix = &f->fmt.pix;
289 int ret; 297 int ret;
@@ -309,7 +317,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
309 icd->user_width = pix->width; 317 icd->user_width = pix->width;
310 icd->user_height = pix->height; 318 icd->user_height = pix->height;
311 icd->colorspace = pix->colorspace; 319 icd->colorspace = pix->colorspace;
312 icf->vb_vidq.field = 320 icd->vb_vidq.field =
313 icd->field = pix->field; 321 icd->field = pix->field;
314 322
315 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 323 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -331,7 +339,6 @@ static int soc_camera_open(struct file *file)
331 dev); 339 dev);
332 struct soc_camera_link *icl = to_soc_camera_link(icd); 340 struct soc_camera_link *icl = to_soc_camera_link(icd);
333 struct soc_camera_host *ici; 341 struct soc_camera_host *ici;
334 struct soc_camera_file *icf;
335 int ret; 342 int ret;
336 343
337 if (!icd->ops) 344 if (!icd->ops)
@@ -340,14 +347,9 @@ static int soc_camera_open(struct file *file)
340 347
341 ici = to_soc_camera_host(icd->dev.parent); 348 ici = to_soc_camera_host(icd->dev.parent);
342 349
343 icf = vmalloc(sizeof(*icf));
344 if (!icf)
345 return -ENOMEM;
346
347 if (!try_module_get(ici->ops->owner)) { 350 if (!try_module_get(ici->ops->owner)) {
348 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); 351 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n");
349 ret = -EINVAL; 352 return -EINVAL;
350 goto emgi;
351 } 353 }
352 354
353 /* 355 /*
@@ -356,7 +358,6 @@ static int soc_camera_open(struct file *file)
356 */ 358 */
357 mutex_lock(&icd->video_lock); 359 mutex_lock(&icd->video_lock);
358 360
359 icf->icd = icd;
360 icd->use_count++; 361 icd->use_count++;
361 362
362 /* Now we really have to activate the camera */ 363 /* Now we really have to activate the camera */
@@ -401,15 +402,15 @@ static int soc_camera_open(struct file *file)
401 * apart from someone else calling open() simultaneously, but 402 * apart from someone else calling open() simultaneously, but
402 * .video_lock is protecting us against it. 403 * .video_lock is protecting us against it.
403 */ 404 */
404 ret = soc_camera_set_fmt(icf, &f); 405 ret = soc_camera_set_fmt(icd, &f);
405 if (ret < 0) 406 if (ret < 0)
406 goto esfmt; 407 goto esfmt;
407 } 408 }
408 409
409 file->private_data = icf; 410 file->private_data = icd;
410 dev_dbg(&icd->dev, "camera device open\n"); 411 dev_dbg(&icd->dev, "camera device open\n");
411 412
412 ici->ops->init_videobuf(&icf->vb_vidq, icd); 413 ici->ops->init_videobuf(&icd->vb_vidq, icd);
413 414
414 mutex_unlock(&icd->video_lock); 415 mutex_unlock(&icd->video_lock);
415 416
@@ -430,15 +431,13 @@ epower:
430 icd->use_count--; 431 icd->use_count--;
431 mutex_unlock(&icd->video_lock); 432 mutex_unlock(&icd->video_lock);
432 module_put(ici->ops->owner); 433 module_put(ici->ops->owner);
433emgi: 434
434 vfree(icf);
435 return ret; 435 return ret;
436} 436}
437 437
438static int soc_camera_close(struct file *file) 438static int soc_camera_close(struct file *file)
439{ 439{
440 struct soc_camera_file *icf = file->private_data; 440 struct soc_camera_device *icd = file->private_data;
441 struct soc_camera_device *icd = icf->icd;
442 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 441 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
443 442
444 mutex_lock(&icd->video_lock); 443 mutex_lock(&icd->video_lock);
@@ -455,12 +454,13 @@ static int soc_camera_close(struct file *file)
455 icl->power(icd->pdev, 0); 454 icl->power(icd->pdev, 0);
456 } 455 }
457 456
457 if (icd->streamer == file)
458 icd->streamer = NULL;
459
458 mutex_unlock(&icd->video_lock); 460 mutex_unlock(&icd->video_lock);
459 461
460 module_put(ici->ops->owner); 462 module_put(ici->ops->owner);
461 463
462 vfree(icf);
463
464 dev_dbg(&icd->dev, "camera device close\n"); 464 dev_dbg(&icd->dev, "camera device close\n");
465 465
466 return 0; 466 return 0;
@@ -469,8 +469,7 @@ static int soc_camera_close(struct file *file)
469static ssize_t soc_camera_read(struct file *file, char __user *buf, 469static ssize_t soc_camera_read(struct file *file, char __user *buf,
470 size_t count, loff_t *ppos) 470 size_t count, loff_t *ppos)
471{ 471{
472 struct soc_camera_file *icf = file->private_data; 472 struct soc_camera_device *icd = file->private_data;
473 struct soc_camera_device *icd = icf->icd;
474 int err = -EINVAL; 473 int err = -EINVAL;
475 474
476 dev_err(&icd->dev, "camera device read not implemented\n"); 475 dev_err(&icd->dev, "camera device read not implemented\n");
@@ -480,13 +479,15 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
480 479
481static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) 480static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
482{ 481{
483 struct soc_camera_file *icf = file->private_data; 482 struct soc_camera_device *icd = file->private_data;
484 struct soc_camera_device *icd = icf->icd;
485 int err; 483 int err;
486 484
487 dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma); 485 dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
488 486
489 err = videobuf_mmap_mapper(&icf->vb_vidq, vma); 487 if (icd->streamer != file)
488 return -EBUSY;
489
490 err = videobuf_mmap_mapper(&icd->vb_vidq, vma);
490 491
491 dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n", 492 dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n",
492 (unsigned long)vma->vm_start, 493 (unsigned long)vma->vm_start,
@@ -498,11 +499,13 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
498 499
499static unsigned int soc_camera_poll(struct file *file, poll_table *pt) 500static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
500{ 501{
501 struct soc_camera_file *icf = file->private_data; 502 struct soc_camera_device *icd = file->private_data;
502 struct soc_camera_device *icd = icf->icd;
503 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 503 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
504 504
505 if (list_empty(&icf->vb_vidq.stream)) { 505 if (icd->streamer != file)
506 return -EBUSY;
507
508 if (list_empty(&icd->vb_vidq.stream)) {
506 dev_err(&icd->dev, "Trying to poll with no queued buffers!\n"); 509 dev_err(&icd->dev, "Trying to poll with no queued buffers!\n");
507 return POLLERR; 510 return POLLERR;
508 } 511 }
@@ -523,24 +526,29 @@ static struct v4l2_file_operations soc_camera_fops = {
523static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, 526static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
524 struct v4l2_format *f) 527 struct v4l2_format *f)
525{ 528{
526 struct soc_camera_file *icf = file->private_data; 529 struct soc_camera_device *icd = file->private_data;
527 struct soc_camera_device *icd = icf->icd;
528 int ret; 530 int ret;
529 531
530 WARN_ON(priv != file->private_data); 532 WARN_ON(priv != file->private_data);
531 533
532 mutex_lock(&icf->vb_vidq.vb_lock); 534 if (icd->streamer && icd->streamer != file)
535 return -EBUSY;
533 536
534 if (icf->vb_vidq.bufs[0]) { 537 mutex_lock(&icd->vb_vidq.vb_lock);
538
539 if (icd->vb_vidq.bufs[0]) {
535 dev_err(&icd->dev, "S_FMT denied: queue initialised\n"); 540 dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
536 ret = -EBUSY; 541 ret = -EBUSY;
537 goto unlock; 542 goto unlock;
538 } 543 }
539 544
540 ret = soc_camera_set_fmt(icf, f); 545 ret = soc_camera_set_fmt(icd, f);
546
547 if (!ret && !icd->streamer)
548 icd->streamer = file;
541 549
542unlock: 550unlock:
543 mutex_unlock(&icf->vb_vidq.vb_lock); 551 mutex_unlock(&icd->vb_vidq.vb_lock);
544 552
545 return ret; 553 return ret;
546} 554}
@@ -548,8 +556,7 @@ unlock:
548static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, 556static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
549 struct v4l2_fmtdesc *f) 557 struct v4l2_fmtdesc *f)
550{ 558{
551 struct soc_camera_file *icf = file->private_data; 559 struct soc_camera_device *icd = file->private_data;
552 struct soc_camera_device *icd = icf->icd;
553 const struct soc_mbus_pixelfmt *format; 560 const struct soc_mbus_pixelfmt *format;
554 561
555 WARN_ON(priv != file->private_data); 562 WARN_ON(priv != file->private_data);
@@ -568,15 +575,14 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
568static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, 575static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
569 struct v4l2_format *f) 576 struct v4l2_format *f)
570{ 577{
571 struct soc_camera_file *icf = file->private_data; 578 struct soc_camera_device *icd = file->private_data;
572 struct soc_camera_device *icd = icf->icd;
573 struct v4l2_pix_format *pix = &f->fmt.pix; 579 struct v4l2_pix_format *pix = &f->fmt.pix;
574 580
575 WARN_ON(priv != file->private_data); 581 WARN_ON(priv != file->private_data);
576 582
577 pix->width = icd->user_width; 583 pix->width = icd->user_width;
578 pix->height = icd->user_height; 584 pix->height = icd->user_height;
579 pix->field = icf->vb_vidq.field; 585 pix->field = icd->vb_vidq.field;
580 pix->pixelformat = icd->current_fmt->host_fmt->fourcc; 586 pix->pixelformat = icd->current_fmt->host_fmt->fourcc;
581 pix->bytesperline = soc_mbus_bytes_per_line(pix->width, 587 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
582 icd->current_fmt->host_fmt); 588 icd->current_fmt->host_fmt);
@@ -592,8 +598,7 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
592static int soc_camera_querycap(struct file *file, void *priv, 598static int soc_camera_querycap(struct file *file, void *priv,
593 struct v4l2_capability *cap) 599 struct v4l2_capability *cap)
594{ 600{
595 struct soc_camera_file *icf = file->private_data; 601 struct soc_camera_device *icd = file->private_data;
596 struct soc_camera_device *icd = icf->icd;
597 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 602 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
598 603
599 WARN_ON(priv != file->private_data); 604 WARN_ON(priv != file->private_data);
@@ -605,8 +610,7 @@ static int soc_camera_querycap(struct file *file, void *priv,
605static int soc_camera_streamon(struct file *file, void *priv, 610static int soc_camera_streamon(struct file *file, void *priv,
606 enum v4l2_buf_type i) 611 enum v4l2_buf_type i)
607{ 612{
608 struct soc_camera_file *icf = file->private_data; 613 struct soc_camera_device *icd = file->private_data;
609 struct soc_camera_device *icd = icf->icd;
610 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 614 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
611 int ret; 615 int ret;
612 616
@@ -615,12 +619,15 @@ static int soc_camera_streamon(struct file *file, void *priv,
615 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 619 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
616 return -EINVAL; 620 return -EINVAL;
617 621
622 if (icd->streamer != file)
623 return -EBUSY;
624
618 mutex_lock(&icd->video_lock); 625 mutex_lock(&icd->video_lock);
619 626
620 v4l2_subdev_call(sd, video, s_stream, 1); 627 v4l2_subdev_call(sd, video, s_stream, 1);
621 628
622 /* This calls buf_queue from host driver's videobuf_queue_ops */ 629 /* This calls buf_queue from host driver's videobuf_queue_ops */
623 ret = videobuf_streamon(&icf->vb_vidq); 630 ret = videobuf_streamon(&icd->vb_vidq);
624 631
625 mutex_unlock(&icd->video_lock); 632 mutex_unlock(&icd->video_lock);
626 633
@@ -630,8 +637,7 @@ static int soc_camera_streamon(struct file *file, void *priv,
630static int soc_camera_streamoff(struct file *file, void *priv, 637static int soc_camera_streamoff(struct file *file, void *priv,
631 enum v4l2_buf_type i) 638 enum v4l2_buf_type i)
632{ 639{
633 struct soc_camera_file *icf = file->private_data; 640 struct soc_camera_device *icd = file->private_data;
634 struct soc_camera_device *icd = icf->icd;
635 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 641 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
636 642
637 WARN_ON(priv != file->private_data); 643 WARN_ON(priv != file->private_data);
@@ -639,13 +645,16 @@ static int soc_camera_streamoff(struct file *file, void *priv,
639 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 645 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
640 return -EINVAL; 646 return -EINVAL;
641 647
648 if (icd->streamer != file)
649 return -EBUSY;
650
642 mutex_lock(&icd->video_lock); 651 mutex_lock(&icd->video_lock);
643 652
644 /* 653 /*
645 * This calls buf_release from host driver's videobuf_queue_ops for all 654 * This calls buf_release from host driver's videobuf_queue_ops for all
646 * remaining buffers. When the last buffer is freed, stop capture 655 * remaining buffers. When the last buffer is freed, stop capture
647 */ 656 */
648 videobuf_streamoff(&icf->vb_vidq); 657 videobuf_streamoff(&icd->vb_vidq);
649 658
650 v4l2_subdev_call(sd, video, s_stream, 0); 659 v4l2_subdev_call(sd, video, s_stream, 0);
651 660
@@ -657,8 +666,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
657static int soc_camera_queryctrl(struct file *file, void *priv, 666static int soc_camera_queryctrl(struct file *file, void *priv,
658 struct v4l2_queryctrl *qc) 667 struct v4l2_queryctrl *qc)
659{ 668{
660 struct soc_camera_file *icf = file->private_data; 669 struct soc_camera_device *icd = file->private_data;
661 struct soc_camera_device *icd = icf->icd;
662 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 670 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
663 int i; 671 int i;
664 672
@@ -689,8 +697,7 @@ static int soc_camera_queryctrl(struct file *file, void *priv,
689static int soc_camera_g_ctrl(struct file *file, void *priv, 697static int soc_camera_g_ctrl(struct file *file, void *priv,
690 struct v4l2_control *ctrl) 698 struct v4l2_control *ctrl)
691{ 699{
692 struct soc_camera_file *icf = file->private_data; 700 struct soc_camera_device *icd = file->private_data;
693 struct soc_camera_device *icd = icf->icd;
694 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 701 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
695 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 702 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
696 int ret; 703 int ret;
@@ -709,8 +716,7 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
709static int soc_camera_s_ctrl(struct file *file, void *priv, 716static int soc_camera_s_ctrl(struct file *file, void *priv,
710 struct v4l2_control *ctrl) 717 struct v4l2_control *ctrl)
711{ 718{
712 struct soc_camera_file *icf = file->private_data; 719 struct soc_camera_device *icd = file->private_data;
713 struct soc_camera_device *icd = icf->icd;
714 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 720 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
715 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 721 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
716 int ret; 722 int ret;
@@ -729,8 +735,7 @@ static int soc_camera_s_ctrl(struct file *file, void *priv,
729static int soc_camera_cropcap(struct file *file, void *fh, 735static int soc_camera_cropcap(struct file *file, void *fh,
730 struct v4l2_cropcap *a) 736 struct v4l2_cropcap *a)
731{ 737{
732 struct soc_camera_file *icf = file->private_data; 738 struct soc_camera_device *icd = file->private_data;
733 struct soc_camera_device *icd = icf->icd;
734 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 739 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
735 740
736 return ici->ops->cropcap(icd, a); 741 return ici->ops->cropcap(icd, a);
@@ -739,14 +744,13 @@ static int soc_camera_cropcap(struct file *file, void *fh,
739static int soc_camera_g_crop(struct file *file, void *fh, 744static int soc_camera_g_crop(struct file *file, void *fh,
740 struct v4l2_crop *a) 745 struct v4l2_crop *a)
741{ 746{
742 struct soc_camera_file *icf = file->private_data; 747 struct soc_camera_device *icd = file->private_data;
743 struct soc_camera_device *icd = icf->icd;
744 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 748 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
745 int ret; 749 int ret;
746 750
747 mutex_lock(&icf->vb_vidq.vb_lock); 751 mutex_lock(&icd->vb_vidq.vb_lock);
748 ret = ici->ops->get_crop(icd, a); 752 ret = ici->ops->get_crop(icd, a);
749 mutex_unlock(&icf->vb_vidq.vb_lock); 753 mutex_unlock(&icd->vb_vidq.vb_lock);
750 754
751 return ret; 755 return ret;
752} 756}
@@ -759,8 +763,7 @@ static int soc_camera_g_crop(struct file *file, void *fh,
759static int soc_camera_s_crop(struct file *file, void *fh, 763static int soc_camera_s_crop(struct file *file, void *fh,
760 struct v4l2_crop *a) 764 struct v4l2_crop *a)
761{ 765{
762 struct soc_camera_file *icf = file->private_data; 766 struct soc_camera_device *icd = file->private_data;
763 struct soc_camera_device *icd = icf->icd;
764 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 767 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
765 struct v4l2_rect *rect = &a->c; 768 struct v4l2_rect *rect = &a->c;
766 struct v4l2_crop current_crop; 769 struct v4l2_crop current_crop;
@@ -773,7 +776,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
773 rect->width, rect->height, rect->left, rect->top); 776 rect->width, rect->height, rect->left, rect->top);
774 777
775 /* Cropping is allowed during a running capture, guard consistency */ 778 /* Cropping is allowed during a running capture, guard consistency */
776 mutex_lock(&icf->vb_vidq.vb_lock); 779 mutex_lock(&icd->vb_vidq.vb_lock);
777 780
778 /* If get_crop fails, we'll let host and / or client drivers decide */ 781 /* If get_crop fails, we'll let host and / or client drivers decide */
779 ret = ici->ops->get_crop(icd, &current_crop); 782 ret = ici->ops->get_crop(icd, &current_crop);
@@ -782,7 +785,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
782 if (ret < 0) { 785 if (ret < 0) {
783 dev_err(&icd->dev, 786 dev_err(&icd->dev,
784 "S_CROP denied: getting current crop failed\n"); 787 "S_CROP denied: getting current crop failed\n");
785 } else if (icf->vb_vidq.bufs[0] && 788 } else if (icd->vb_vidq.bufs[0] &&
786 (a->c.width != current_crop.c.width || 789 (a->c.width != current_crop.c.width ||
787 a->c.height != current_crop.c.height)) { 790 a->c.height != current_crop.c.height)) {
788 dev_err(&icd->dev, 791 dev_err(&icd->dev,
@@ -792,7 +795,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
792 ret = ici->ops->set_crop(icd, a); 795 ret = ici->ops->set_crop(icd, a);
793 } 796 }
794 797
795 mutex_unlock(&icf->vb_vidq.vb_lock); 798 mutex_unlock(&icd->vb_vidq.vb_lock);
796 799
797 return ret; 800 return ret;
798} 801}
@@ -800,8 +803,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
800static int soc_camera_g_parm(struct file *file, void *fh, 803static int soc_camera_g_parm(struct file *file, void *fh,
801 struct v4l2_streamparm *a) 804 struct v4l2_streamparm *a)
802{ 805{
803 struct soc_camera_file *icf = file->private_data; 806 struct soc_camera_device *icd = file->private_data;
804 struct soc_camera_device *icd = icf->icd;
805 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 807 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
806 808
807 if (ici->ops->get_parm) 809 if (ici->ops->get_parm)
@@ -813,8 +815,7 @@ static int soc_camera_g_parm(struct file *file, void *fh,
813static int soc_camera_s_parm(struct file *file, void *fh, 815static int soc_camera_s_parm(struct file *file, void *fh,
814 struct v4l2_streamparm *a) 816 struct v4l2_streamparm *a)
815{ 817{
816 struct soc_camera_file *icf = file->private_data; 818 struct soc_camera_device *icd = file->private_data;
817 struct soc_camera_device *icd = icf->icd;
818 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 819 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
819 820
820 if (ici->ops->set_parm) 821 if (ici->ops->set_parm)
@@ -826,8 +827,7 @@ static int soc_camera_s_parm(struct file *file, void *fh,
826static int soc_camera_g_chip_ident(struct file *file, void *fh, 827static int soc_camera_g_chip_ident(struct file *file, void *fh,
827 struct v4l2_dbg_chip_ident *id) 828 struct v4l2_dbg_chip_ident *id)
828{ 829{
829 struct soc_camera_file *icf = file->private_data; 830 struct soc_camera_device *icd = file->private_data;
830 struct soc_camera_device *icd = icf->icd;
831 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 831 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
832 832
833 return v4l2_subdev_call(sd, core, g_chip_ident, id); 833 return v4l2_subdev_call(sd, core, g_chip_ident, id);
@@ -837,8 +837,7 @@ static int soc_camera_g_chip_ident(struct file *file, void *fh,
837static int soc_camera_g_register(struct file *file, void *fh, 837static int soc_camera_g_register(struct file *file, void *fh,
838 struct v4l2_dbg_register *reg) 838 struct v4l2_dbg_register *reg)
839{ 839{
840 struct soc_camera_file *icf = file->private_data; 840 struct soc_camera_device *icd = file->private_data;
841 struct soc_camera_device *icd = icf->icd;
842 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 841 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
843 842
844 return v4l2_subdev_call(sd, core, g_register, reg); 843 return v4l2_subdev_call(sd, core, g_register, reg);
@@ -847,8 +846,7 @@ static int soc_camera_g_register(struct file *file, void *fh,
847static int soc_camera_s_register(struct file *file, void *fh, 846static int soc_camera_s_register(struct file *file, void *fh,
848 struct v4l2_dbg_register *reg) 847 struct v4l2_dbg_register *reg)
849{ 848{
850 struct soc_camera_file *icf = file->private_data; 849 struct soc_camera_device *icd = file->private_data;
851 struct soc_camera_device *icd = icf->icd;
852 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 850 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
853 851
854 return v4l2_subdev_call(sd, core, s_register, reg); 852 return v4l2_subdev_call(sd, core, s_register, reg);
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 2ce957301f77..86e3631764ef 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -21,6 +21,8 @@
21 21
22extern struct bus_type soc_camera_bus_type; 22extern struct bus_type soc_camera_bus_type;
23 23
24struct file;
25
24struct soc_camera_device { 26struct soc_camera_device {
25 struct list_head list; 27 struct list_head list;
26 struct device dev; 28 struct device dev;
@@ -41,10 +43,7 @@ struct soc_camera_device {
41 /* soc_camera.c private count. Only accessed with .video_lock held */ 43 /* soc_camera.c private count. Only accessed with .video_lock held */
42 int use_count; 44 int use_count;
43 struct mutex video_lock; /* Protects device data */ 45 struct mutex video_lock; /* Protects device data */
44}; 46 struct file *streamer; /* stream owner */
45
46struct soc_camera_file {
47 struct soc_camera_device *icd;
48 struct videobuf_queue vb_vidq; 47 struct videobuf_queue vb_vidq;
49}; 48};
50 49
@@ -79,7 +78,7 @@ struct soc_camera_host_ops {
79 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); 78 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
80 void (*init_videobuf)(struct videobuf_queue *, 79 void (*init_videobuf)(struct videobuf_queue *,
81 struct soc_camera_device *); 80 struct soc_camera_device *);
82 int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); 81 int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *);
83 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); 82 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
84 int (*set_bus_param)(struct soc_camera_device *, __u32); 83 int (*set_bus_param)(struct soc_camera_device *, __u32);
85 int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *); 84 int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *);