Re: [PATCH v3 3/5] media: qcom: camss: vfe: Fix VFE reset while another line is streaming

From: Loic Poulain

Date: Mon Sep 28 2026 - 04:04:40 EST


On Mon, Sep 28, 2026 at 8:43 AM Hitesh Patel <hitesh@xxxxxxxxxxxxxx> wrote:
>
> vfe_disable_output() stops the write masters of the line being
> disabled and then resets the whole VFE. The reset is not limited to
> that line.
>
> When two lines of one VFE stream at the same time, which is the case
> whenever a CSID demultiplexes several virtual channels to different
> RDIs, stopping the first line resets the VFE underneath the second
> line. The second line's write master configuration is wiped, the
> buffers it had in flight are never completed, and the VFE is left in
> a state in which the next global reset is not acknowledged. Stopping
> or restarting the second line then fails with:
>
> VFE reset timeout
>
> Only reset the VFE when the line being disabled is the last one
> streaming, which vfe->stream_count already tracks. Stopping the
> line's write masters is enough to quiesce that line on its own. With
> a single line streaming, the reset happens exactly as before.
>
> Fixes: 7319cdf189bb ("media: camss: Add support for VFE hardware version Titan 170")
> Signed-off-by: Hitesh Patel <hitesh@xxxxxxxxxxxxxx>
> ---
> drivers/media/platform/qcom/camss/camss-vfe.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index c14d97a131..3442dacc80 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -814,6 +814,7 @@ static int vfe_disable_output(struct vfe_line *line)
> struct vfe_output *output = &line->output;
> unsigned long flags;
> unsigned int i;
> + bool last;
>
> spin_lock_irqsave(&vfe->output_lock, flags);
> for (i = 0; i < output->wm_num; i++)
> @@ -821,6 +822,13 @@ static int vfe_disable_output(struct vfe_line *line)
> output->gen2.active_num = 0;
> spin_unlock_irqrestore(&vfe->output_lock, flags);
>
> + mutex_lock(&vfe->stream_lock);
> + last = vfe->stream_count == 1;
> + mutex_unlock(&vfe->stream_lock);
> +
> + if (!last)
> + return 0;

Instead I would move the vfe_reset() into vfe_disable().

> +
> return vfe_reset(vfe);
> }
>
> --
> 2.43.0
>