mirror of https://gitee.com/openkylin/linux.git
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 <slongerbeam@gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
6b8952db06
commit
3ef46bc97c
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue