aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/media/imx/imx7-media-csi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/media/imx/imx7-media-csi.c')
-rw-r--r--drivers/staging/media/imx/imx7-media-csi.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index a3f3df901704..3046f880c014 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -499,6 +499,7 @@ static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd,
struct v4l2_subdev_format *sink_fmt)
{
struct imx7_csi *csi = v4l2_get_subdevdata(sd);
+ struct media_entity *src;
struct media_pad *pad;
int ret;
@@ -509,11 +510,21 @@ static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd,
if (!csi->src_sd)
return -EPIPE;
+ src = &csi->src_sd->entity;
+
/*
- * find the entity that is selected by the CSI mux. This is needed
+ * if the source is neither a CSI MUX or CSI-2 get the one directly
+ * upstream from this CSI
+ */
+ if (src->function != MEDIA_ENT_F_VID_IF_BRIDGE &&
+ src->function != MEDIA_ENT_F_VID_MUX)
+ src = &csi->sd.entity;
+
+ /*
+ * find the entity that is selected by the source. This is needed
* to distinguish between a parallel or CSI-2 pipeline.
*/
- pad = imx_media_pipeline_pad(&csi->src_sd->entity, 0, 0, true);
+ pad = imx_media_pipeline_pad(src, 0, 0, true);
if (!pad)
return -ENODEV;
@@ -1164,12 +1175,12 @@ static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier,
struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK];
- /* The bound subdev must always be the CSI mux */
- if (WARN_ON(sd->entity.function != MEDIA_ENT_F_VID_MUX))
- return -ENXIO;
-
- /* Mark it as such via its group id */
- sd->grp_id = IMX_MEDIA_GRP_ID_CSI_MUX;
+ /*
+ * If the subdev is a video mux, it must be one of the CSI
+ * muxes. Mark it as such via its group id.
+ */
+ if (sd->entity.function == MEDIA_ENT_F_VID_MUX)
+ sd->grp_id = IMX_MEDIA_GRP_ID_CSI_MUX;
return v4l2_create_fwnode_links_to_pad(sd, sink);
}
@@ -1180,7 +1191,7 @@ static const struct v4l2_async_notifier_operations imx7_csi_notify_ops = {
static int imx7_csi_async_register(struct imx7_csi *csi)
{
- struct v4l2_async_subdev *asd = NULL;
+ struct v4l2_async_subdev *asd;
struct fwnode_handle *ep;
int ret;
@@ -1189,19 +1200,13 @@ static int imx7_csi_async_register(struct imx7_csi *csi)
ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
FWNODE_GRAPH_ENDPOINT_NEXT);
if (ep) {
- asd = kzalloc(sizeof(*asd), GFP_KERNEL);
- if (!asd) {
- fwnode_handle_put(ep);
- return -ENOMEM;
- }
-
- ret = v4l2_async_notifier_add_fwnode_remote_subdev(
- &csi->notifier, ep, asd);
+ asd = v4l2_async_notifier_add_fwnode_remote_subdev(
+ &csi->notifier, ep, struct v4l2_async_subdev);
fwnode_handle_put(ep);
- if (ret) {
- kfree(asd);
+ if (IS_ERR(asd)) {
+ ret = PTR_ERR(asd);
/* OK if asd already exists */
if (ret != -EEXIST)
return ret;