On Mon Sep 28 17:45:05 2026 +0530, Hitesh Patel 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
> 
> Move the reset to vfe_disable() and do it under stream_lock, as part
> of the decrement that makes the count reach zero, so that exactly one
> caller resets and no line can be enabled while the reset runs.
> 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")
> Cc: [email protected]
> Signed-off-by: Hitesh Patel <[email protected]>
> Suggested-by: Bryan O'Donoghue <[email protected]>
> Reviewed-by: Bryan O'Donoghue <[email protected]>
> [bod: Converted vfe_disable_output to void]
> Signed-off-by: Bryan O'Donoghue <[email protected]>

Patch committed.

Thanks,
Bryan O'Donoghue

 drivers/media/platform/qcom/camss/camss-vfe.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

---

diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c 
b/drivers/media/platform/qcom/camss/camss-vfe.c
index c14d97a131f6..2680a9914765 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -808,7 +808,7 @@ int vfe_put_output(struct vfe_line *line)
        return 0;
 }
 
-static int vfe_disable_output(struct vfe_line *line)
+static void vfe_disable_output(struct vfe_line *line)
 {
        struct vfe_device *vfe = to_vfe(line);
        struct vfe_output *output = &line->output;
@@ -820,8 +820,6 @@ static int vfe_disable_output(struct vfe_line *line)
                vfe->res->hw_ops->vfe_wm_stop(vfe, output->wm_idx[i]);
        output->gen2.active_num = 0;
        spin_unlock_irqrestore(&vfe->output_lock, flags);
-
-       return vfe_reset(vfe);
 }
 
 /*
@@ -833,21 +831,19 @@ static int vfe_disable_output(struct vfe_line *line)
 int vfe_disable(struct vfe_line *line)
 {
        struct vfe_device *vfe = to_vfe(line);
-       int ret;
+       int ret = 0;
 
-       ret = vfe_disable_output(line);
-       if (ret)
-               goto error;
+       vfe_disable_output(line);
 
        vfe_put_output(line);
 
        mutex_lock(&vfe->stream_lock);
 
-       vfe->stream_count--;
+       if (--vfe->stream_count == 0)
+               ret = vfe_reset(vfe);
 
        mutex_unlock(&vfe->stream_lock);
 
-error:
        return ret;
 }
 
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to