In order to allow for automatic media device entities linking
from the level of libv4l plugin the open system call shouldn't
fail, as the libv4l plugins can begin their job not until it
succeeds.
This patch allows for leaving the  pipeline not linked on
open and postpones verifying it to the moment when streamon
callback is called.

Signed-off-by: Jacek Anaszewski <j.anaszew...@samsung.com>
Acked-by: Kyungmin Park <kyungmin.p...@samsung.com>
---
 drivers/media/platform/exynos4-is/media-dev.c |   45 ++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/exynos4-is/media-dev.c 
b/drivers/media/platform/exynos4-is/media-dev.c
index c867c46..3732663 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -217,7 +217,7 @@ static int __fimc_pipeline_open(struct 
exynos_media_pipeline *ep,
                fimc_pipeline_prepare(p, me);
 
        sd = p->subdevs[IDX_SENSOR];
-       if (sd == NULL)
+       if (sd == NULL && !fmd->user_subdev_api)
                return -EINVAL;
 
        /* Disable PXLASYNC clock if this pipeline includes FIMC-IS */
@@ -277,10 +277,46 @@ static int __fimc_pipeline_s_stream(struct 
exynos_media_pipeline *ep, bool on)
                { IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP },
        };
        struct fimc_pipeline *p = to_fimc_pipeline(ep);
-       int i, ret = 0;
+       struct fimc_md *fmd = 
entity_to_fimc_mdev(&p->subdevs[IDX_CSIS]->entity);
+       enum fimc_subdev_index sd_id;
+       int i = 0, ret = 0;
 
-       if (p->subdevs[IDX_SENSOR] == NULL)
-               return -ENODEV;
+       /*
+        * Sensor might not be discovered upon device open
+        * due to not linked pipeline. User space is expected to
+        * link the pipeline prior calling VIDIOC_STREAMON ioctl,
+        * when in user_subdev_api mode.
+        */
+       while (p->subdevs[IDX_SENSOR] == NULL) {
+               /*
+                * Sensor must be already discovered if
+                * we are in non user_subdev_api mode.
+                */
+               if (!fmd->user_subdev_api) {
+                       return -ENODEV;
+               } else if (i++ == 0) {
+                       /* Determine which entity is last in the pipeline */
+                       if (p->subdevs[IDX_FIMC])
+                               sd_id = IDX_FIMC;
+                       else if (p->subdevs[IDX_IS_ISP])
+                               sd_id = IDX_IS_ISP;
+                       else if (p->subdevs[IDX_FLITE])
+                               sd_id = IDX_FLITE;
+                       else
+                               return -ENODEV;
+
+                       ret = __fimc_pipeline_open(ep,
+                                       &p->subdevs[sd_id]->entity,
+                                       true);
+                       if (ret < 0)
+                               return ret;
+
+                       if (p->subdevs[IDX_SENSOR] == NULL)
+                               return -ENODEV;
+               } else {
+                       return -ENODEV;
+               }
+       }
 
        /* Wait until all devices in the chain are powered up */
        async_synchronize_full_domain(&ep->async_domain);
@@ -293,6 +329,7 @@ static int __fimc_pipeline_s_stream(struct 
exynos_media_pipeline *ep, bool on)
                if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
                        goto error;
        }
+
        return 0;
 error:
        for (; i >= 0; i--) {
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to