From 3ef46bc97ca2c918b7657a08220c7340a9bb07a2 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Fri, 10 May 2019 17:50:11 -0400 Subject: [PATCH] media: staging/imx: Improve pipeline searching 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 Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/imx/imx-ic-common.c | 4 +- drivers/staging/media/imx/imx-ic-prp.c | 4 +- drivers/staging/media/imx/imx-ic.h | 1 - drivers/staging/media/imx/imx-media-csi.c | 13 +- drivers/staging/media/imx/imx-media-fim.c | 4 - .../staging/media/imx/imx-media-internal-sd.c | 5 +- drivers/staging/media/imx/imx-media-utils.c | 142 ++++++++++-------- drivers/staging/media/imx/imx-media-vdic.c | 5 +- drivers/staging/media/imx/imx-media.h | 20 +-- drivers/staging/media/imx/imx7-media-csi.c | 2 +- 10 files changed, 100 insertions(+), 100 deletions(-) diff --git a/drivers/staging/media/imx/imx-ic-common.c b/drivers/staging/media/imx/imx-ic-common.c index 7919c3cb2842..6df1ffb53895 100644 --- a/drivers/staging/media/imx/imx-ic-common.c +++ b/drivers/staging/media/imx/imx-ic-common.c @@ -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) { diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c index 3caeba38638c..5b4af3cfe670 100644 --- a/drivers/staging/media/imx/imx-ic-prp.c +++ b/drivers/staging/media/imx/imx-ic-prp.c @@ -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; diff --git a/drivers/staging/media/imx/imx-ic.h b/drivers/staging/media/imx/imx-ic.h index e1acd4c15789..587c191c3eab 100644 --- a/drivers/staging/media/imx/imx-ic.h +++ b/drivers/staging/media/imx/imx-ic.h @@ -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; diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 611b89b5ffcb..d2f880938af9 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -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)) { diff --git a/drivers/staging/media/imx/imx-media-fim.c b/drivers/staging/media/imx/imx-media-fim.c index 6c081518abff..3a9182933508 100644 --- a/drivers/staging/media/imx/imx-media-fim.c +++ b/drivers/staging/media/imx/imx-media-fim.c @@ -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); diff --git a/drivers/staging/media/imx/imx-media-internal-sd.c b/drivers/staging/media/imx/imx-media-internal-sd.c index c96f273e2e3d..cb1e4cdd5079 100644 --- a/drivers/staging/media/imx/imx-media-internal-sd.c +++ b/drivers/staging/media/imx/imx-media-internal-sd.c @@ -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); diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c index 78f9f6fd80dc..b5b8a3b7730a 100644 --- a/drivers/staging/media/imx/imx-media-utils.c +++ b/drivers/staging/media/imx/imx-media-utils.c @@ -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 find_pipeline_pad(imxmd, pad->entity, - grp_id, upstream); + 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 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,42 +857,19 @@ 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); - -/* - * Find a source pad 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 media_pad *pad; - - pad = find_pipeline_pad(imxmd, start_entity, grp_id, true); - if (!pad) - return ERR_PTR(-ENODEV); - - return pad; -} -EXPORT_SYMBOL_GPL(imx_media_find_upstream_pad); +EXPORT_SYMBOL_GPL(imx_media_pipeline_csi2_channel); /* * Find a subdev reached upstream from the given start entity in @@ -881,19 +877,37 @@ EXPORT_SYMBOL_GPL(imx_media_find_upstream_pad); * 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) +imx_media_pipeline_subdev(struct media_entity *start_entity, u32 grp_id, + 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, grp_id, 0, upstream); + if (!me) return ERR_PTR(-ENODEV); - return sd; + return media_entity_to_v4l2_subdev(me); } -EXPORT_SYMBOL_GPL(imx_media_find_upstream_subdev); +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 video_device * +imx_media_pipeline_video_device(struct media_entity *start_entity, + enum v4l2_buf_type buftype, bool upstream) +{ + struct media_entity *me; + + me = find_pipeline_entity(start_entity, 0, buftype, upstream); + if (!me) + return ERR_PTR(-ENODEV); + + return media_entity_to_video_device(me); +} +EXPORT_SYMBOL_GPL(imx_media_pipeline_video_device); /* * Turn current pipeline streaming on/off starting from entity. diff --git a/drivers/staging/media/imx/imx-media-vdic.c b/drivers/staging/media/imx/imx-media-vdic.c index 1cbefb508e73..4d90eecb04a2 100644 --- a/drivers/staging/media/imx/imx-media-vdic.c +++ b/drivers/staging/media/imx/imx-media-vdic.c @@ -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); diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index 980104594f6f..8a60bdafe2da 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h @@ -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); diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c index 75514618d021..7eda67ed1bd7 100644 --- a/drivers/staging/media/imx/imx7-media-csi.c +++ b/drivers/staging/media/imx/imx7-media-csi.c @@ -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);