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]