media: staging/imx: Improve pipeline searching
authorSteve Longerbeam <slongerbeam@gmail.com>
Fri, 10 May 2019 21:50:11 +0000 (17:50 -0400)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Tue, 28 May 2019 18:15:36 +0000 (14:15 -0400)
Export find_pipeline_pad(), renaming to imx_media_pipeline_pad(), and
extend its functionality to allow searching for video devices in the
enabled pipeline in addition to sub-devices.

As part of this:

- Rename imx_media_find_mipi_csi2_channel() to
  imx_media_pipeline_csi2_channel().

- Remove imx_media_find_upstream_pad(), it is redundant now.

- Rename imx_media_find_upstream_subdev() to imx_media_pipeline_subdev()
  with an additional boolean argument for searching upstream or downstream.

- Add imx_media_pipeline_video_device() which is analogous to
  imx_media_pipeline_subdev() but searches for video devices.

- Remove imxmd pointer arg from all of the functions above, it was
  never used in those functions. With that change the i.MX5/6 CSI,
  VDIC, and IC sub-devices no longer require the media_device.

Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/staging/media/imx/imx-ic-common.c
drivers/staging/media/imx/imx-ic-prp.c
drivers/staging/media/imx/imx-ic.h
drivers/staging/media/imx/imx-media-csi.c
drivers/staging/media/imx/imx-media-fim.c
drivers/staging/media/imx/imx-media-internal-sd.c
drivers/staging/media/imx/imx-media-utils.c
drivers/staging/media/imx/imx-media-vdic.c
drivers/staging/media/imx/imx-media.h
drivers/staging/media/imx/imx7-media-csi.c

index 7919c3c..6df1ffb 100644 (file)
@@ -18,12 +18,11 @@ static struct imx_ic_ops *ic_ops[IC_NUM_OPS] = {
        [IC_TASK_VIEWFINDER]     = &imx_ic_prpencvf_ops,
 };
 
-struct v4l2_subdev *imx_media_ic_register(struct imx_media_dev *imxmd,
+struct v4l2_subdev *imx_media_ic_register(struct v4l2_device *v4l2_dev,
                                          struct device *ipu_dev,
                                          struct ipu_soc *ipu,
                                          u32 grp_id)
 {
-       struct v4l2_device *v4l2_dev = &imxmd->v4l2_dev;
        struct imx_ic_priv *priv;
        int ret;
 
@@ -33,7 +32,6 @@ struct v4l2_subdev *imx_media_ic_register(struct imx_media_dev *imxmd,
 
        priv->ipu_dev = ipu_dev;
        priv->ipu = ipu;
-       priv->md = imxmd;
 
        /* get our IC task id */
        switch (grp_id) {
index 3caeba3..5b4af3c 100644 (file)
@@ -298,8 +298,8 @@ static int prp_link_validate(struct v4l2_subdev *sd,
        if (ret)
                return ret;
 
-       csi = imx_media_find_upstream_subdev(ic_priv->md, &ic_priv->sd.entity,
-                                            IMX_MEDIA_GRP_ID_IPU_CSI);
+       csi = imx_media_pipeline_subdev(&ic_priv->sd.entity,
+                                       IMX_MEDIA_GRP_ID_IPU_CSI, true);
        if (IS_ERR(csi))
                csi = NULL;
 
index e1acd4c..587c191 100644 (file)
@@ -12,7 +12,6 @@
 struct imx_ic_priv {
        struct device *ipu_dev;
        struct ipu_soc *ipu;
-       struct imx_media_dev *md;
        struct v4l2_subdev sd;
        int    task_id;
        void   *task_priv;
index 611b89b..d2f8809 100644 (file)
@@ -56,7 +56,6 @@ struct csi_skip_desc {
 struct csi_priv {
        struct device *dev;
        struct ipu_soc *ipu;
-       struct imx_media_dev *md;
        struct v4l2_subdev sd;
        struct media_pad pad[CSI_NUM_PADS];
        /* the video device at IDMAC output pad */
@@ -178,8 +177,8 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv,
                 * CSI-2 receiver if it is in the path, otherwise stay
                 * with video mux.
                 */
-               sd = imx_media_find_upstream_subdev(priv->md, src,
-                                                   IMX_MEDIA_GRP_ID_CSI2);
+               sd = imx_media_pipeline_subdev(src, IMX_MEDIA_GRP_ID_CSI2,
+                                              true);
                if (!IS_ERR(sd))
                        src = &sd->entity;
        }
@@ -193,7 +192,7 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv,
                src = &priv->sd.entity;
 
        /* get source pad of entity directly upstream from src */
-       pad = imx_media_find_upstream_pad(priv->md, src, 0);
+       pad = imx_media_pipeline_pad(src, 0, 0, true);
        if (IS_ERR(pad))
                return PTR_ERR(pad);
 
@@ -1134,8 +1133,7 @@ static int csi_link_validate(struct v4l2_subdev *sd,
                 */
 #if 0
                mutex_unlock(&priv->lock);
-               vc_num = imx_media_find_mipi_csi2_channel(priv->md,
-                                                         &priv->sd.entity);
+               vc_num = imx_media_find_mipi_csi2_channel(&priv->sd.entity);
                if (vc_num < 0)
                        return vc_num;
                mutex_lock(&priv->lock);
@@ -1749,9 +1747,6 @@ static int csi_registered(struct v4l2_subdev *sd)
        int i, ret;
        u32 code;
 
-       /* get media device */
-       priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
-
        /* get handle to IPU CSI */
        csi = ipu_csi_get(priv->ipu, priv->csi_id);
        if (IS_ERR(csi)) {
index 6c08151..3a91829 100644 (file)
@@ -37,8 +37,6 @@ enum {
 #define FIM_CL_TOLERANCE_MAX_DEF   0 /* no max tolerance (unbounded) */
 
 struct imx_media_fim {
-       struct imx_media_dev *md;
-
        /* the owning subdev of this fim instance */
        struct v4l2_subdev *sd;
 
@@ -470,8 +468,6 @@ struct imx_media_fim *imx_media_fim_init(struct v4l2_subdev *sd)
        if (!fim)
                return ERR_PTR(-ENOMEM);
 
-       /* get media device */
-       fim->md = dev_get_drvdata(sd->v4l2_dev->dev);
        fim->sd = sd;
 
        spin_lock_init(&fim->lock);
index c96f273..cb1e4cd 100644 (file)
@@ -31,7 +31,7 @@ struct internal_subdev {
        u32 grp_id;
        struct internal_pad pad[MAX_INTERNAL_PADS];
 
-       struct v4l2_subdev * (*sync_register)(struct imx_media_dev *imxmd,
+       struct v4l2_subdev * (*sync_register)(struct v4l2_device *v4l2_dev,
                                              struct device *ipu_dev,
                                              struct ipu_soc *ipu,
                                              u32 grp_id);
@@ -224,7 +224,8 @@ int imx_media_register_ipu_internal_subdevs(struct imx_media_dev *imxmd,
                        continue;
 
                mutex_unlock(&imxmd->mutex);
-               sd = intsd->sync_register(imxmd, ipu_dev, ipu, intsd->grp_id);
+               sd = intsd->sync_register(&imxmd->v4l2_dev, ipu_dev, ipu,
+                                         intsd->grp_id);
                mutex_lock(&imxmd->mutex);
                if (IS_ERR(sd)) {
                        ret = PTR_ERR(sd);
index 78f9f6f..b5b8a3b 100644 (file)
@@ -768,19 +768,22 @@ void imx_media_add_video_device(struct imx_media_dev *imxmd,
 EXPORT_SYMBOL_GPL(imx_media_add_video_device);
 
 /*
- * Search upstream/downstream for a subdevice in the current pipeline
- * with given grp_id, starting from start_entity. Returns the subdev's
- * source/sink pad that it was reached from. If grp_id is zero, just
- * returns the nearest source/sink pad to start_entity. Must be called
- * with mdev->graph_mutex held.
+ * Search upstream/downstream for a subdevice or video device pad in the
+ * current pipeline, starting from start_entity. Returns the device's
+ * source/sink pad that it was reached from. Must be called with
+ * mdev->graph_mutex held.
+ *
+ * If grp_id != 0, finds a subdevice's pad of given grp_id.
+ * Else If buftype != 0, finds a video device's pad of given buffer type.
+ * Else, returns the nearest source/sink pad to start_entity.
  */
-static struct media_pad *
-find_pipeline_pad(struct imx_media_dev *imxmd,
-                 struct media_entity *start_entity,
-                 u32 grp_id, bool upstream)
+struct media_pad *
+imx_media_pipeline_pad(struct media_entity *start_entity, u32 grp_id,
+                      enum v4l2_buf_type buftype, bool upstream)
 {
        struct media_entity *me = start_entity;
        struct media_pad *pad = NULL;
+       struct video_device *vfd;
        struct v4l2_subdev *sd;
        int i;
 
@@ -792,16 +795,27 @@ find_pipeline_pad(struct imx_media_dev *imxmd,
                        continue;
 
                pad = media_entity_remote_pad(spad);
-               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
+               if (!pad)
                        continue;
 
-               if (grp_id != 0) {
-                       sd = media_entity_to_v4l2_subdev(pad->entity);
-                       if (sd->grp_id & grp_id)
-                               return pad;
+               if (grp_id) {
+                       if (is_media_entity_v4l2_subdev(pad->entity)) {
+                               sd = media_entity_to_v4l2_subdev(pad->entity);
+                               if (sd->grp_id & grp_id)
+                                       return pad;
+                       }
+
+                       return imx_media_pipeline_pad(pad->entity, grp_id,
+                                                     buftype, upstream);
+               } else if (buftype) {
+                       if (is_media_entity_v4l2_video_device(pad->entity)) {
+                               vfd = media_entity_to_video_device(pad->entity);
+                               if (buftype == vfd->queue->type)
+                                       return pad;
+                       }
 
-                       return find_pipeline_pad(imxmd, pad->entity,
-                                                grp_id, upstream);
+                       return imx_media_pipeline_pad(pad->entity, grp_id,
+                                                     buftype, upstream);
                } else {
                        return pad;
                }
@@ -809,28 +823,33 @@ find_pipeline_pad(struct imx_media_dev *imxmd,
 
        return NULL;
 }
+EXPORT_SYMBOL_GPL(imx_media_pipeline_pad);
 
 /*
- * Search upstream for a subdev in the current pipeline with
- * given grp_id. Must be called with mdev->graph_mutex held.
+ * Search upstream/downstream for a subdev or video device in the current
+ * pipeline. Must be called with mdev->graph_mutex held.
  */
-static struct v4l2_subdev *
-find_upstream_subdev(struct imx_media_dev *imxmd,
-                    struct media_entity *start_entity,
-                    u32 grp_id)
+static struct media_entity *
+find_pipeline_entity(struct media_entity *start, u32 grp_id,
+                    enum v4l2_buf_type buftype, bool upstream)
 {
+       struct media_pad *pad = NULL;
+       struct video_device *vfd;
        struct v4l2_subdev *sd;
-       struct media_pad *pad;
 
-       if (is_media_entity_v4l2_subdev(start_entity)) {
-               sd = media_entity_to_v4l2_subdev(start_entity);
+       if (grp_id && is_media_entity_v4l2_subdev(start)) {
+               sd = media_entity_to_v4l2_subdev(start);
                if (sd->grp_id & grp_id)
-                       return sd;
+                       return &sd->entity;
+       } else if (buftype && is_media_entity_v4l2_video_device(start)) {
+               vfd = media_entity_to_video_device(pad->entity);
+               if (buftype == vfd->queue->type)
+                       return &vfd->entity;
        }
 
-       pad = find_pipeline_pad(imxmd, start_entity, grp_id, true);
+       pad = imx_media_pipeline_pad(start, grp_id, buftype, upstream);
 
-       return pad ? media_entity_to_v4l2_subdev(pad->entity) : NULL;
+       return pad ? pad->entity : NULL;
 }
 
 /*
@@ -838,62 +857,57 @@ find_upstream_subdev(struct imx_media_dev *imxmd,
  * start entity in the current pipeline.
  * Must be called with mdev->graph_mutex held.
  */
-int imx_media_find_mipi_csi2_channel(struct imx_media_dev *imxmd,
-                                    struct media_entity *start_entity)
+int imx_media_pipeline_csi2_channel(struct media_entity *start_entity)
 {
        struct media_pad *pad;
        int ret = -EPIPE;
 
-       pad = find_pipeline_pad(imxmd, start_entity, IMX_MEDIA_GRP_ID_CSI2,
-                               true);
-       if (pad) {
+       pad = imx_media_pipeline_pad(start_entity, IMX_MEDIA_GRP_ID_CSI2,
+                                    0, true);
+       if (pad)
                ret = pad->index - 1;
-               dev_dbg(imxmd->md.dev, "found vc%d from %s\n",
-                       ret, start_entity->name);
-       }
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(imx_media_find_mipi_csi2_channel);
+EXPORT_SYMBOL_GPL(imx_media_pipeline_csi2_channel);
 
 /*
- * Find a source pad reached upstream from the given start entity in
- * the current pipeline. Must be called with mdev->graph_mutex held.
+ * Find a subdev reached upstream from the given start entity in
+ * the current pipeline.
+ * Must be called with mdev->graph_mutex held.
  */
-struct media_pad *
-imx_media_find_upstream_pad(struct imx_media_dev *imxmd,
-                           struct media_entity *start_entity,
-                           u32 grp_id)
+struct v4l2_subdev *
+imx_media_pipeline_subdev(struct media_entity *start_entity, u32 grp_id,
+                         bool upstream)
 {
-       struct media_pad *pad;
+       struct media_entity *me;
 
-       pad = find_pipeline_pad(imxmd, start_entity, grp_id, true);
-       if (!pad)
+       me = find_pipeline_entity(start_entity, grp_id, 0, upstream);
+       if (!me)
                return ERR_PTR(-ENODEV);
 
-       return pad;
+       return media_entity_to_v4l2_subdev(me);
 }
-EXPORT_SYMBOL_GPL(imx_media_find_upstream_pad);
+EXPORT_SYMBOL_GPL(imx_media_pipeline_subdev);
 
 /*
  * Find a subdev reached upstream from the given start entity in
  * the current pipeline.
  * Must be called with mdev->graph_mutex held.
  */
-struct v4l2_subdev *
-imx_media_find_upstream_subdev(struct imx_media_dev *imxmd,
-                              struct media_entity *start_entity,
-                              u32 grp_id)
+struct video_device *
+imx_media_pipeline_video_device(struct media_entity *start_entity,
+                               enum v4l2_buf_type buftype, bool upstream)
 {
-       struct v4l2_subdev *sd;
+       struct media_entity *me;
 
-       sd = find_upstream_subdev(imxmd, start_entity, grp_id);
-       if (!sd)
+       me = find_pipeline_entity(start_entity, 0, buftype, upstream);
+       if (!me)
                return ERR_PTR(-ENODEV);
 
-       return sd;
+       return media_entity_to_video_device(me);
 }
-EXPORT_SYMBOL_GPL(imx_media_find_upstream_subdev);
+EXPORT_SYMBOL_GPL(imx_media_pipeline_video_device);
 
 /*
  * Turn current pipeline streaming on/off starting from entity.
index 1cbefb5..4d90eec 100644 (file)
@@ -61,7 +61,6 @@ struct vdic_priv {
        struct device *ipu_dev;
        struct ipu_soc *ipu;
 
-       struct imx_media_dev *md;
        struct v4l2_subdev   sd;
        struct media_pad pad[VDIC_NUM_PADS];
 
@@ -923,12 +922,11 @@ static const struct v4l2_subdev_internal_ops vdic_internal_ops = {
        .unregistered = vdic_unregistered,
 };
 
-struct v4l2_subdev *imx_media_vdic_register(struct imx_media_dev *imxmd,
+struct v4l2_subdev *imx_media_vdic_register(struct v4l2_device *v4l2_dev,
                                            struct device *ipu_dev,
                                            struct ipu_soc *ipu,
                                            u32 grp_id)
 {
-       struct v4l2_device *v4l2_dev = &imxmd->v4l2_dev;
        struct vdic_priv *priv;
        int ret;
 
@@ -938,7 +936,6 @@ struct v4l2_subdev *imx_media_vdic_register(struct imx_media_dev *imxmd,
 
        priv->ipu_dev = ipu_dev;
        priv->ipu = ipu;
-       priv->md = imxmd;
 
        v4l2_subdev_init(&priv->sd, &vdic_subdev_ops);
        v4l2_set_subdevdata(&priv->sd, priv);
index 9801045..8a60bda 100644 (file)
@@ -186,16 +186,16 @@ imx_media_find_subdev_by_devname(struct imx_media_dev *imxmd,
                                 const char *devname);
 void imx_media_add_video_device(struct imx_media_dev *imxmd,
                                struct imx_media_video_dev *vdev);
-int imx_media_find_mipi_csi2_channel(struct imx_media_dev *imxmd,
-                                    struct media_entity *start_entity);
+int imx_media_pipeline_csi2_channel(struct media_entity *start_entity);
 struct media_pad *
-imx_media_find_upstream_pad(struct imx_media_dev *imxmd,
-                           struct media_entity *start_entity,
-                           u32 grp_id);
+imx_media_pipeline_pad(struct media_entity *start_entity, u32 grp_id,
+                      enum v4l2_buf_type buftype, bool upstream);
 struct v4l2_subdev *
-imx_media_find_upstream_subdev(struct imx_media_dev *imxmd,
-                              struct media_entity *start_entity,
-                              u32 grp_id);
+imx_media_pipeline_subdev(struct media_entity *start_entity, u32 grp_id,
+                         bool upstream);
+struct video_device *
+imx_media_pipeline_video_device(struct media_entity *start_entity,
+                               enum v4l2_buf_type buftype, bool upstream);
 
 struct imx_media_dma_buf {
        void          *virt;
@@ -246,14 +246,14 @@ int imx_media_of_add_csi(struct imx_media_dev *imxmd,
                         struct device_node *csi_np);
 
 /* imx-media-vdic.c */
-struct v4l2_subdev *imx_media_vdic_register(struct imx_media_dev *imxmd,
+struct v4l2_subdev *imx_media_vdic_register(struct v4l2_device *v4l2_dev,
                                            struct device *ipu_dev,
                                            struct ipu_soc *ipu,
                                            u32 grp_id);
 int imx_media_vdic_unregister(struct v4l2_subdev *sd);
 
 /* imx-ic-common.c */
-struct v4l2_subdev *imx_media_ic_register(struct imx_media_dev *imxmd,
+struct v4l2_subdev *imx_media_ic_register(struct v4l2_device *v4l2_dev,
                                          struct device *ipu_dev,
                                          struct ipu_soc *ipu,
                                          u32 grp_id);
index 7551461..7eda67e 100644 (file)
@@ -450,7 +450,7 @@ static int imx7_csi_get_upstream_endpoint(struct imx7_csi *csi,
 
 skip_video_mux:
        /* get source pad of entity directly upstream from src */
-       pad = imx_media_find_upstream_pad(csi->imxmd, src, 0);
+       pad = imx_media_pipeline_pad(src, 0, 0, true);
        if (IS_ERR(pad))
                return PTR_ERR(pad);