diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2012-12-24 07:31:33 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-01-04 22:36:23 -0500 |
commit | dd669e907cbe1cf33f9cbbff79af2b5c271cdd89 (patch) | |
tree | aeb887abff9f1641fc6bc4bc44a31196aafb793b | |
parent | 8a97d4c11756ab6bab8582126d0f1b5c00b067ad (diff) |
[media] soc-camera: remove struct soc_camera_device::video_lock
Currently soc-camera has a per-device node lock, used for video operations
and a per-host lock for code paths, modifying host's pipeline. Manipulating
the two locks increases complexity and doesn't bring any advantages. This
patch removes the per-device lock and uses the per-host lock for all
operations.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/platform/soc_camera/atmel-isi.c | 4 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/mx1_camera.c | 3 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/mx2_camera.c | 1 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/mx3_camera.c | 4 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/omap1_camera.c | 4 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/pxa_camera.c | 6 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | 4 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/soc_camera.c | 51 | ||||
-rw-r--r-- | include/media/soc_camera.h | 3 |
9 files changed, 35 insertions, 45 deletions
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index c8d748a31944..eba1f6b2b0fb 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c | |||
@@ -745,7 +745,7 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, | |||
745 | return formats; | 745 | return formats; |
746 | } | 746 | } |
747 | 747 | ||
748 | /* Called with .video_lock held */ | 748 | /* Called with .host_lock held */ |
749 | static int isi_camera_add_device(struct soc_camera_device *icd) | 749 | static int isi_camera_add_device(struct soc_camera_device *icd) |
750 | { | 750 | { |
751 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 751 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
@@ -770,7 +770,7 @@ static int isi_camera_add_device(struct soc_camera_device *icd) | |||
770 | icd->devnum); | 770 | icd->devnum); |
771 | return 0; | 771 | return 0; |
772 | } | 772 | } |
773 | /* Called with .video_lock held */ | 773 | /* Called with .host_lock held */ |
774 | static void isi_camera_remove_device(struct soc_camera_device *icd) | 774 | static void isi_camera_remove_device(struct soc_camera_device *icd) |
775 | { | 775 | { |
776 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 776 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c index 674ded646b66..4b661e87d8b1 100644 --- a/drivers/media/platform/soc_camera/mx1_camera.c +++ b/drivers/media/platform/soc_camera/mx1_camera.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
29 | #include <linux/mutex.h> | ||
30 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
31 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
32 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
@@ -373,7 +372,7 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q, | |||
373 | videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->parent, | 372 | videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->parent, |
374 | &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 373 | &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, |
375 | V4L2_FIELD_NONE, | 374 | V4L2_FIELD_NONE, |
376 | sizeof(struct mx1_buffer), icd, &icd->video_lock); | 375 | sizeof(struct mx1_buffer), icd, &icd->host_lock); |
377 | } | 376 | } |
378 | 377 | ||
379 | static int mclk_get_divisor(struct mx1_camera_dev *pcdev) | 378 | static int mclk_get_divisor(struct mx1_camera_dev *pcdev) |
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index 28d5c84eef82..bf2740f7c4d1 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/time.h> | 28 | #include <linux/time.h> |
29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/mutex.h> | ||
32 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
33 | 32 | ||
34 | #include <media/v4l2-common.h> | 33 | #include <media/v4l2-common.h> |
diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index 574d12522f95..37d0d0ef8adf 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c | |||
@@ -510,7 +510,7 @@ static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam, | |||
510 | clk_set_rate(mx3_cam->clk, rate); | 510 | clk_set_rate(mx3_cam->clk, rate); |
511 | } | 511 | } |
512 | 512 | ||
513 | /* Called with .video_lock held */ | 513 | /* Called with .host_lock held */ |
514 | static int mx3_camera_add_device(struct soc_camera_device *icd) | 514 | static int mx3_camera_add_device(struct soc_camera_device *icd) |
515 | { | 515 | { |
516 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 516 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
@@ -530,7 +530,7 @@ static int mx3_camera_add_device(struct soc_camera_device *icd) | |||
530 | return 0; | 530 | return 0; |
531 | } | 531 | } |
532 | 532 | ||
533 | /* Called with .video_lock held */ | 533 | /* Called with .host_lock held */ |
534 | static void mx3_camera_remove_device(struct soc_camera_device *icd) | 534 | static void mx3_camera_remove_device(struct soc_camera_device *icd) |
535 | { | 535 | { |
536 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 536 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index 8f9c1f44544c..dcf7be814776 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c | |||
@@ -1383,12 +1383,12 @@ static void omap1_cam_init_videobuf(struct videobuf_queue *q, | |||
1383 | videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops, | 1383 | videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops, |
1384 | icd->parent, &pcdev->lock, | 1384 | icd->parent, &pcdev->lock, |
1385 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | 1385 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, |
1386 | sizeof(struct omap1_cam_buf), icd, &icd->video_lock); | 1386 | sizeof(struct omap1_cam_buf), icd, &icd->host_lock); |
1387 | else | 1387 | else |
1388 | videobuf_queue_sg_init(q, &omap1_videobuf_ops, | 1388 | videobuf_queue_sg_init(q, &omap1_videobuf_ops, |
1389 | icd->parent, &pcdev->lock, | 1389 | icd->parent, &pcdev->lock, |
1390 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | 1390 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, |
1391 | sizeof(struct omap1_cam_buf), icd, &icd->video_lock); | 1391 | sizeof(struct omap1_cam_buf), icd, &icd->host_lock); |
1392 | 1392 | ||
1393 | /* use videobuf mode (auto)selected with the module parameter */ | 1393 | /* use videobuf mode (auto)selected with the module parameter */ |
1394 | pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG; | 1394 | pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG; |
diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 8ff961eec39d..f3c1b6202425 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c | |||
@@ -842,7 +842,7 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q, | |||
842 | */ | 842 | */ |
843 | videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock, | 843 | videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock, |
844 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | 844 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, |
845 | sizeof(struct pxa_buffer), icd, &icd->video_lock); | 845 | sizeof(struct pxa_buffer), icd, &icd->host_lock); |
846 | } | 846 | } |
847 | 847 | ||
848 | static u32 mclk_get_divisor(struct platform_device *pdev, | 848 | static u32 mclk_get_divisor(struct platform_device *pdev, |
@@ -958,7 +958,7 @@ static irqreturn_t pxa_camera_irq(int irq, void *data) | |||
958 | /* | 958 | /* |
959 | * The following two functions absolutely depend on the fact, that | 959 | * The following two functions absolutely depend on the fact, that |
960 | * there can be only one camera on PXA quick capture interface | 960 | * there can be only one camera on PXA quick capture interface |
961 | * Called with .video_lock held | 961 | * Called with .host_lock held |
962 | */ | 962 | */ |
963 | static int pxa_camera_add_device(struct soc_camera_device *icd) | 963 | static int pxa_camera_add_device(struct soc_camera_device *icd) |
964 | { | 964 | { |
@@ -978,7 +978,7 @@ static int pxa_camera_add_device(struct soc_camera_device *icd) | |||
978 | return 0; | 978 | return 0; |
979 | } | 979 | } |
980 | 980 | ||
981 | /* Called with .video_lock held */ | 981 | /* Called with .host_lock held */ |
982 | static void pxa_camera_remove_device(struct soc_camera_device *icd) | 982 | static void pxa_camera_remove_device(struct soc_camera_device *icd) |
983 | { | 983 | { |
984 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 984 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 9f021043cfe6..cdf173bbcc93 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | |||
@@ -543,7 +543,7 @@ static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev) | |||
543 | return NULL; | 543 | return NULL; |
544 | } | 544 | } |
545 | 545 | ||
546 | /* Called with .video_lock held */ | 546 | /* Called with .host_lock held */ |
547 | static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) | 547 | static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) |
548 | { | 548 | { |
549 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 549 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
@@ -587,7 +587,7 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) | |||
587 | return 0; | 587 | return 0; |
588 | } | 588 | } |
589 | 589 | ||
590 | /* Called with .video_lock held */ | 590 | /* Called with .host_lock held */ |
591 | static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) | 591 | static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) |
592 | { | 592 | { |
593 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 593 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 6552856ea59b..ae89f980e82b 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c | |||
@@ -383,7 +383,7 @@ static int soc_camera_prepare_buf(struct file *file, void *priv, | |||
383 | return vb2_prepare_buf(&icd->vb2_vidq, b); | 383 | return vb2_prepare_buf(&icd->vb2_vidq, b); |
384 | } | 384 | } |
385 | 385 | ||
386 | /* Always entered with .video_lock held */ | 386 | /* Always entered with .host_lock held */ |
387 | static int soc_camera_init_user_formats(struct soc_camera_device *icd) | 387 | static int soc_camera_init_user_formats(struct soc_camera_device *icd) |
388 | { | 388 | { |
389 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 389 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
@@ -450,7 +450,7 @@ egfmt: | |||
450 | return ret; | 450 | return ret; |
451 | } | 451 | } |
452 | 452 | ||
453 | /* Always entered with .video_lock held */ | 453 | /* Always entered with .host_lock held */ |
454 | static void soc_camera_free_user_formats(struct soc_camera_device *icd) | 454 | static void soc_camera_free_user_formats(struct soc_camera_device *icd) |
455 | { | 455 | { |
456 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 456 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
@@ -526,7 +526,7 @@ static int soc_camera_open(struct file *file) | |||
526 | ici = to_soc_camera_host(icd->parent); | 526 | ici = to_soc_camera_host(icd->parent); |
527 | mutex_unlock(&list_lock); | 527 | mutex_unlock(&list_lock); |
528 | 528 | ||
529 | if (mutex_lock_interruptible(&icd->video_lock)) | 529 | if (mutex_lock_interruptible(&ici->host_lock)) |
530 | return -ERESTARTSYS; | 530 | return -ERESTARTSYS; |
531 | if (!try_module_get(ici->ops->owner)) { | 531 | if (!try_module_get(ici->ops->owner)) { |
532 | dev_err(icd->pdev, "Couldn't lock capture bus driver.\n"); | 532 | dev_err(icd->pdev, "Couldn't lock capture bus driver.\n"); |
@@ -555,9 +555,7 @@ static int soc_camera_open(struct file *file) | |||
555 | if (icl->reset) | 555 | if (icl->reset) |
556 | icl->reset(icd->pdev); | 556 | icl->reset(icd->pdev); |
557 | 557 | ||
558 | mutex_lock(&ici->host_lock); | ||
559 | ret = ici->ops->add(icd); | 558 | ret = ici->ops->add(icd); |
560 | mutex_unlock(&ici->host_lock); | ||
561 | if (ret < 0) { | 559 | if (ret < 0) { |
562 | dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret); | 560 | dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret); |
563 | goto eiciadd; | 561 | goto eiciadd; |
@@ -576,7 +574,7 @@ static int soc_camera_open(struct file *file) | |||
576 | * Try to configure with default parameters. Notice: this is the | 574 | * Try to configure with default parameters. Notice: this is the |
577 | * very first open, so, we cannot race against other calls, | 575 | * very first open, so, we cannot race against other calls, |
578 | * apart from someone else calling open() simultaneously, but | 576 | * apart from someone else calling open() simultaneously, but |
579 | * .video_lock is protecting us against it. | 577 | * .host_lock is protecting us against it. |
580 | */ | 578 | */ |
581 | ret = soc_camera_set_fmt(icd, &f); | 579 | ret = soc_camera_set_fmt(icd, &f); |
582 | if (ret < 0) | 580 | if (ret < 0) |
@@ -591,7 +589,7 @@ static int soc_camera_open(struct file *file) | |||
591 | } | 589 | } |
592 | v4l2_ctrl_handler_setup(&icd->ctrl_handler); | 590 | v4l2_ctrl_handler_setup(&icd->ctrl_handler); |
593 | } | 591 | } |
594 | mutex_unlock(&icd->video_lock); | 592 | mutex_unlock(&ici->host_lock); |
595 | 593 | ||
596 | file->private_data = icd; | 594 | file->private_data = icd; |
597 | dev_dbg(icd->pdev, "camera device open\n"); | 595 | dev_dbg(icd->pdev, "camera device open\n"); |
@@ -599,7 +597,7 @@ static int soc_camera_open(struct file *file) | |||
599 | return 0; | 597 | return 0; |
600 | 598 | ||
601 | /* | 599 | /* |
602 | * First four errors are entered with the .video_lock held | 600 | * First four errors are entered with the .host_lock held |
603 | * and use_count == 1 | 601 | * and use_count == 1 |
604 | */ | 602 | */ |
605 | einitvb: | 603 | einitvb: |
@@ -608,14 +606,12 @@ esfmt: | |||
608 | eresume: | 606 | eresume: |
609 | __soc_camera_power_off(icd); | 607 | __soc_camera_power_off(icd); |
610 | epower: | 608 | epower: |
611 | mutex_lock(&ici->host_lock); | ||
612 | ici->ops->remove(icd); | 609 | ici->ops->remove(icd); |
613 | mutex_unlock(&ici->host_lock); | ||
614 | eiciadd: | 610 | eiciadd: |
615 | icd->use_count--; | 611 | icd->use_count--; |
616 | module_put(ici->ops->owner); | 612 | module_put(ici->ops->owner); |
617 | emodule: | 613 | emodule: |
618 | mutex_unlock(&icd->video_lock); | 614 | mutex_unlock(&ici->host_lock); |
619 | 615 | ||
620 | return ret; | 616 | return ret; |
621 | } | 617 | } |
@@ -625,7 +621,7 @@ static int soc_camera_close(struct file *file) | |||
625 | struct soc_camera_device *icd = file->private_data; | 621 | struct soc_camera_device *icd = file->private_data; |
626 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 622 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
627 | 623 | ||
628 | mutex_lock(&icd->video_lock); | 624 | mutex_lock(&ici->host_lock); |
629 | icd->use_count--; | 625 | icd->use_count--; |
630 | if (!icd->use_count) { | 626 | if (!icd->use_count) { |
631 | pm_runtime_suspend(&icd->vdev->dev); | 627 | pm_runtime_suspend(&icd->vdev->dev); |
@@ -633,16 +629,14 @@ static int soc_camera_close(struct file *file) | |||
633 | 629 | ||
634 | if (ici->ops->init_videobuf2) | 630 | if (ici->ops->init_videobuf2) |
635 | vb2_queue_release(&icd->vb2_vidq); | 631 | vb2_queue_release(&icd->vb2_vidq); |
636 | mutex_lock(&ici->host_lock); | ||
637 | ici->ops->remove(icd); | 632 | ici->ops->remove(icd); |
638 | mutex_unlock(&ici->host_lock); | ||
639 | 633 | ||
640 | __soc_camera_power_off(icd); | 634 | __soc_camera_power_off(icd); |
641 | } | 635 | } |
642 | 636 | ||
643 | if (icd->streamer == file) | 637 | if (icd->streamer == file) |
644 | icd->streamer = NULL; | 638 | icd->streamer = NULL; |
645 | mutex_unlock(&icd->video_lock); | 639 | mutex_unlock(&ici->host_lock); |
646 | 640 | ||
647 | module_put(ici->ops->owner); | 641 | module_put(ici->ops->owner); |
648 | 642 | ||
@@ -679,13 +673,13 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) | |||
679 | if (icd->streamer != file) | 673 | if (icd->streamer != file) |
680 | return -EBUSY; | 674 | return -EBUSY; |
681 | 675 | ||
682 | if (mutex_lock_interruptible(&icd->video_lock)) | 676 | if (mutex_lock_interruptible(&ici->host_lock)) |
683 | return -ERESTARTSYS; | 677 | return -ERESTARTSYS; |
684 | if (ici->ops->init_videobuf) | 678 | if (ici->ops->init_videobuf) |
685 | err = videobuf_mmap_mapper(&icd->vb_vidq, vma); | 679 | err = videobuf_mmap_mapper(&icd->vb_vidq, vma); |
686 | else | 680 | else |
687 | err = vb2_mmap(&icd->vb2_vidq, vma); | 681 | err = vb2_mmap(&icd->vb2_vidq, vma); |
688 | mutex_unlock(&icd->video_lock); | 682 | mutex_unlock(&ici->host_lock); |
689 | 683 | ||
690 | dev_dbg(icd->pdev, "vma start=0x%08lx, size=%ld, ret=%d\n", | 684 | dev_dbg(icd->pdev, "vma start=0x%08lx, size=%ld, ret=%d\n", |
691 | (unsigned long)vma->vm_start, | 685 | (unsigned long)vma->vm_start, |
@@ -704,26 +698,28 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt) | |||
704 | if (icd->streamer != file) | 698 | if (icd->streamer != file) |
705 | return POLLERR; | 699 | return POLLERR; |
706 | 700 | ||
707 | mutex_lock(&icd->video_lock); | 701 | mutex_lock(&ici->host_lock); |
708 | if (ici->ops->init_videobuf && list_empty(&icd->vb_vidq.stream)) | 702 | if (ici->ops->init_videobuf && list_empty(&icd->vb_vidq.stream)) |
709 | dev_err(icd->pdev, "Trying to poll with no queued buffers!\n"); | 703 | dev_err(icd->pdev, "Trying to poll with no queued buffers!\n"); |
710 | else | 704 | else |
711 | res = ici->ops->poll(file, pt); | 705 | res = ici->ops->poll(file, pt); |
712 | mutex_unlock(&icd->video_lock); | 706 | mutex_unlock(&ici->host_lock); |
713 | return res; | 707 | return res; |
714 | } | 708 | } |
715 | 709 | ||
716 | void soc_camera_lock(struct vb2_queue *vq) | 710 | void soc_camera_lock(struct vb2_queue *vq) |
717 | { | 711 | { |
718 | struct soc_camera_device *icd = vb2_get_drv_priv(vq); | 712 | struct soc_camera_device *icd = vb2_get_drv_priv(vq); |
719 | mutex_lock(&icd->video_lock); | 713 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
714 | mutex_lock(&ici->host_lock); | ||
720 | } | 715 | } |
721 | EXPORT_SYMBOL(soc_camera_lock); | 716 | EXPORT_SYMBOL(soc_camera_lock); |
722 | 717 | ||
723 | void soc_camera_unlock(struct vb2_queue *vq) | 718 | void soc_camera_unlock(struct vb2_queue *vq) |
724 | { | 719 | { |
725 | struct soc_camera_device *icd = vb2_get_drv_priv(vq); | 720 | struct soc_camera_device *icd = vb2_get_drv_priv(vq); |
726 | mutex_unlock(&icd->video_lock); | 721 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
722 | mutex_unlock(&ici->host_lock); | ||
727 | } | 723 | } |
728 | EXPORT_SYMBOL(soc_camera_unlock); | 724 | EXPORT_SYMBOL(soc_camera_unlock); |
729 | 725 | ||
@@ -1213,7 +1209,7 @@ static int soc_camera_probe(struct soc_camera_device *icd) | |||
1213 | * itself is protected against concurrent open() calls, but we also have | 1209 | * itself is protected against concurrent open() calls, but we also have |
1214 | * to protect our data. | 1210 | * to protect our data. |
1215 | */ | 1211 | */ |
1216 | mutex_lock(&icd->video_lock); | 1212 | mutex_lock(&ici->host_lock); |
1217 | 1213 | ||
1218 | ret = soc_camera_video_start(icd); | 1214 | ret = soc_camera_video_start(icd); |
1219 | if (ret < 0) | 1215 | if (ret < 0) |
@@ -1227,16 +1223,14 @@ static int soc_camera_probe(struct soc_camera_device *icd) | |||
1227 | icd->field = mf.field; | 1223 | icd->field = mf.field; |
1228 | } | 1224 | } |
1229 | 1225 | ||
1230 | mutex_lock(&ici->host_lock); | ||
1231 | ici->ops->remove(icd); | 1226 | ici->ops->remove(icd); |
1232 | mutex_unlock(&ici->host_lock); | ||
1233 | 1227 | ||
1234 | mutex_unlock(&icd->video_lock); | 1228 | mutex_unlock(&ici->host_lock); |
1235 | 1229 | ||
1236 | return 0; | 1230 | return 0; |
1237 | 1231 | ||
1238 | evidstart: | 1232 | evidstart: |
1239 | mutex_unlock(&icd->video_lock); | 1233 | mutex_unlock(&ici->host_lock); |
1240 | soc_camera_free_user_formats(icd); | 1234 | soc_camera_free_user_formats(icd); |
1241 | eiufmt: | 1235 | eiufmt: |
1242 | ectrl: | 1236 | ectrl: |
@@ -1451,7 +1445,6 @@ static int soc_camera_device_register(struct soc_camera_device *icd) | |||
1451 | icd->devnum = num; | 1445 | icd->devnum = num; |
1452 | icd->use_count = 0; | 1446 | icd->use_count = 0; |
1453 | icd->host_priv = NULL; | 1447 | icd->host_priv = NULL; |
1454 | mutex_init(&icd->video_lock); | ||
1455 | 1448 | ||
1456 | list_add_tail(&icd->list, &devices); | 1449 | list_add_tail(&icd->list, &devices); |
1457 | 1450 | ||
@@ -1509,7 +1502,7 @@ static int video_dev_create(struct soc_camera_device *icd) | |||
1509 | vdev->release = video_device_release; | 1502 | vdev->release = video_device_release; |
1510 | vdev->tvnorms = V4L2_STD_UNKNOWN; | 1503 | vdev->tvnorms = V4L2_STD_UNKNOWN; |
1511 | vdev->ctrl_handler = &icd->ctrl_handler; | 1504 | vdev->ctrl_handler = &icd->ctrl_handler; |
1512 | vdev->lock = &icd->video_lock; | 1505 | vdev->lock = &ici->host_lock; |
1513 | 1506 | ||
1514 | icd->vdev = vdev; | 1507 | icd->vdev = vdev; |
1515 | 1508 | ||
@@ -1517,7 +1510,7 @@ static int video_dev_create(struct soc_camera_device *icd) | |||
1517 | } | 1510 | } |
1518 | 1511 | ||
1519 | /* | 1512 | /* |
1520 | * Called from soc_camera_probe() above (with .video_lock held???) | 1513 | * Called from soc_camera_probe() above with .host_lock held |
1521 | */ | 1514 | */ |
1522 | static int soc_camera_video_start(struct soc_camera_device *icd) | 1515 | static int soc_camera_video_start(struct soc_camera_device *icd) |
1523 | { | 1516 | { |
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 0370a9517282..5a662c981484 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h | |||
@@ -46,9 +46,8 @@ struct soc_camera_device { | |||
46 | int num_user_formats; | 46 | int num_user_formats; |
47 | enum v4l2_field field; /* Preserve field over close() */ | 47 | enum v4l2_field field; /* Preserve field over close() */ |
48 | void *host_priv; /* Per-device host private data */ | 48 | void *host_priv; /* Per-device host private data */ |
49 | /* soc_camera.c private count. Only accessed with .video_lock held */ | 49 | /* soc_camera.c private count. Only accessed with .host_lock held */ |
50 | int use_count; | 50 | int use_count; |
51 | struct mutex video_lock; /* Protects device data */ | ||
52 | struct file *streamer; /* stream owner */ | 51 | struct file *streamer; /* stream owner */ |
53 | union { | 52 | union { |
54 | struct videobuf_queue vb_vidq; | 53 | struct videobuf_queue vb_vidq; |