Commit 3ef46bc9 authored by Steve Longerbeam's avatar Steve Longerbeam Committed by Mauro Carvalho Chehab

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: default avatarSteve Longerbeam <slongerbeam@gmail.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 6b8952db
......@@ -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 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.
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment