On Fri Nov 7 11:34:33 2025 +0100, Michael Tretter wrote:
> Request the upstream mbus_config in csi_start, which starts the stream,
> instead of caching it in link_validate.
> 
> This allows to get rid of the mbus_cfg field in the struct csi_priv and
> avoids state in the driver.
> 
> Fixes: 4a34ec8e470c ("[media] media: imx: Add CSI subdev driver")
> Cc: [email protected]
> Reviewed-by: Frank Li <[email protected]>
> Signed-off-by: Michael Tretter <[email protected]>
> Reviewed-by: Philipp Zabel <[email protected]>
> Signed-off-by: Frank Li <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/staging/media/imx/imx-media-csi.c | 40 ++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 16 deletions(-)

---

diff --git a/drivers/staging/media/imx/imx-media-csi.c 
b/drivers/staging/media/imx/imx-media-csi.c
index 725478bc2026..dc594b286f73 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -97,9 +97,6 @@ struct csi_priv {
        /* the mipi virtual channel number at link validate */
        int vc_num;
 
-       /* media bus config of the upstream subdevice CSI is receiving from */
-       struct v4l2_mbus_config mbus_cfg;
-
        spinlock_t irqlock; /* protect eof_irq handler */
        struct timer_list eof_timeout_timer;
        int eof_irq;
@@ -403,7 +400,8 @@ static void csi_idmac_unsetup_vb2_buf(struct csi_priv *priv,
 }
 
 /* init the SMFC IDMAC channel */
-static int csi_idmac_setup_channel(struct csi_priv *priv)
+static int csi_idmac_setup_channel(struct csi_priv *priv,
+                                  struct v4l2_mbus_config *mbus_cfg)
 {
        struct imx_media_video_dev *vdev = priv->vdev;
        const struct imx_media_pixfmt *incc;
@@ -432,7 +430,7 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
        image.phys0 = phys[0];
        image.phys1 = phys[1];
 
-       passthrough = requires_passthrough(&priv->mbus_cfg, infmt, incc);
+       passthrough = requires_passthrough(mbus_cfg, infmt, incc);
        passthrough_cycles = 1;
 
        /*
@@ -572,11 +570,12 @@ static void csi_idmac_unsetup(struct csi_priv *priv,
        csi_idmac_unsetup_vb2_buf(priv, state);
 }
 
-static int csi_idmac_setup(struct csi_priv *priv)
+static int csi_idmac_setup(struct csi_priv *priv,
+                          struct v4l2_mbus_config *mbus_cfg)
 {
        int ret;
 
-       ret = csi_idmac_setup_channel(priv);
+       ret = csi_idmac_setup_channel(priv, mbus_cfg);
        if (ret)
                return ret;
 
@@ -595,7 +594,8 @@ static int csi_idmac_setup(struct csi_priv *priv)
        return 0;
 }
 
-static int csi_idmac_start(struct csi_priv *priv)
+static int csi_idmac_start(struct csi_priv *priv,
+                          struct v4l2_mbus_config *mbus_cfg)
 {
        struct imx_media_video_dev *vdev = priv->vdev;
        int ret;
@@ -619,7 +619,7 @@ static int csi_idmac_start(struct csi_priv *priv)
        priv->last_eof = false;
        priv->nfb4eof = false;
 
-       ret = csi_idmac_setup(priv);
+       ret = csi_idmac_setup(priv, mbus_cfg);
        if (ret) {
                v4l2_err(&priv->sd, "csi_idmac_setup failed: %d\n", ret);
                goto out_free_dma_buf;
@@ -701,7 +701,8 @@ static void csi_idmac_stop(struct csi_priv *priv)
 }
 
 /* Update the CSI whole sensor and active windows */
-static int csi_setup(struct csi_priv *priv)
+static int csi_setup(struct csi_priv *priv,
+                    struct v4l2_mbus_config *mbus_cfg)
 {
        struct v4l2_mbus_framefmt *infmt, *outfmt;
        const struct imx_media_pixfmt *incc;
@@ -719,7 +720,7 @@ static int csi_setup(struct csi_priv *priv)
         * if cycles is set, we need to handle this over multiple cycles as
         * generic/bayer data
         */
-       if (is_parallel_bus(&priv->mbus_cfg) && incc->cycles) {
+       if (is_parallel_bus(mbus_cfg) && incc->cycles) {
                if_fmt.width *= incc->cycles;
                crop.width *= incc->cycles;
        }
@@ -730,7 +731,7 @@ static int csi_setup(struct csi_priv *priv)
                             priv->crop.width == 2 * priv->compose.width,
                             priv->crop.height == 2 * priv->compose.height);
 
-       ipu_csi_init_interface(priv->csi, &priv->mbus_cfg, &if_fmt, outfmt);
+       ipu_csi_init_interface(priv->csi, mbus_cfg, &if_fmt, outfmt);
 
        ipu_csi_set_dest(priv->csi, priv->dest);
 
@@ -745,9 +746,17 @@ static int csi_setup(struct csi_priv *priv)
 
 static int csi_start(struct csi_priv *priv)
 {
+       struct v4l2_mbus_config mbus_cfg = { .type = 0 };
        struct v4l2_fract *input_fi, *output_fi;
        int ret;
 
+       ret = csi_get_upstream_mbus_config(priv, &mbus_cfg);
+       if (ret) {
+               v4l2_err(&priv->sd,
+                        "failed to get upstream media bus configuration\n");
+               return ret;
+       }
+
        input_fi = &priv->frame_interval[CSI_SINK_PAD];
        output_fi = &priv->frame_interval[priv->active_output_pad];
 
@@ -758,7 +767,7 @@ static int csi_start(struct csi_priv *priv)
                return ret;
 
        /* Skip first few frames from a BT.656 source */
-       if (priv->mbus_cfg.type == V4L2_MBUS_BT656) {
+       if (mbus_cfg.type == V4L2_MBUS_BT656) {
                u32 delay_usec, bad_frames = 20;
 
                delay_usec = DIV_ROUND_UP_ULL((u64)USEC_PER_SEC *
@@ -769,12 +778,12 @@ static int csi_start(struct csi_priv *priv)
        }
 
        if (priv->dest == IPU_CSI_DEST_IDMAC) {
-               ret = csi_idmac_start(priv);
+               ret = csi_idmac_start(priv, &mbus_cfg);
                if (ret)
                        goto stop_upstream;
        }
 
-       ret = csi_setup(priv);
+       ret = csi_setup(priv, &mbus_cfg);
        if (ret)
                goto idmac_stop;
 
@@ -1138,7 +1147,6 @@ static int csi_link_validate(struct v4l2_subdev *sd,
 
        mutex_lock(&priv->lock);
 
-       priv->mbus_cfg = mbus_cfg;
        is_csi2 = !is_parallel_bus(&mbus_cfg);
        if (is_csi2) {
                /*
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to