On Fri Jul 4 11:21:34 2025 +0200, Hans de Goede wrote: > Commit c7194b21809e ("media: atomisp: On streamoff wait for buffers owned > by the CSS to be given back") added draining of the CSS buffer queue to > the beginning of atomisp_stop_stream(). > > But it turns out that when telling the CSS to stop streaming it needs at > least 1 buffer queued, because the CSS firmware waits for a frame to be > completed before stopping and without buffers it cannot complete a frame. > > At the end of atomisp_stop_stream() it is always safe to return buffer > ownership to the videobuf2-core. Either atomisp_css_stop() has successfully > stopped the stream; or the atomisp_reset() later on which power-cycles > the ISP will definitely have stopped the stream. > > Drop the draining of the CSS buffer queue to fix the "stop stream timeout." > error and move the atomisp_flush_video_pipe() call after atomisp_reset(), > passing false for the warn_on_css_frames flag since some buffers still > being marked as owned by the CSS expected on stream off. > > Also increase the timeout in destroy_stream(), since this waits for > the last frame to be completed this can take longer then 40 ms. When e.g. > using a framerate of 15 fps, this could take 66ms, make the timeout 200 ms > to be on the safe side. > > Signed-off-by: Hans de Goede <ha...@kernel.org> > Reviewed-by: Andy Shevchenko <a...@kernel.org> > Link: https://lore.kernel.org/r/20250505210008.152659-6-hdego...@redhat.com > Signed-off-by: Mauro Carvalho Chehab <mchehab+hua...@kernel.org>
Patch committed. Thanks, Mauro Carvalho Chehab .../staging/media/atomisp/pci/atomisp_compat_css20.c | 2 +- drivers/staging/media/atomisp/pci/atomisp_fops.c | 5 +---- drivers/staging/media/atomisp/pci/atomisp_ioctl.c | 20 ++------------------ drivers/staging/media/atomisp/pci/atomisp_subdev.h | 3 --- 4 files changed, 4 insertions(+), 26 deletions(-) --- diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c index bc97fa2c374c..be5f37f4a6fd 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c @@ -387,7 +387,7 @@ static int __destroy_stream(struct atomisp_sub_device *asd, } if (stream_env->stream_state == CSS_STREAM_STARTED) { - timeout = jiffies + msecs_to_jiffies(40); + timeout = jiffies + msecs_to_jiffies(200); while (1) { if (ia_css_stream_has_stopped(stream_env->stream)) break; diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c index 57da7ddb1503..c7aef066f209 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c @@ -234,9 +234,6 @@ static int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd, if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM)) return -EINVAL; - if (pipe->stopping) - return -EINVAL; - space = ATOMISP_CSS_Q_DEPTH - atomisp_buffers_in_css(pipe); while (space--) { struct ia_css_frame *frame; @@ -367,7 +364,7 @@ static void atomisp_buf_queue(struct vb2_buffer *vb) mutex_lock(&asd->isp->mutex); ret = atomisp_pipe_check(pipe, false); - if (ret || pipe->stopping) { + if (ret) { spin_lock_irqsave(&pipe->irq_lock, irqflags); atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR); spin_unlock_irqrestore(&pipe->irq_lock, irqflags); diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c index fecba2588e38..bb8b2f2213b0 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c @@ -865,22 +865,6 @@ static void atomisp_stop_stream(struct atomisp_video_pipe *pipe, unsigned long flags; int ret; - /* - * There is no guarantee that the buffers queued to / owned by the ISP - * will properly be returned to the queue when stopping. Set a flag to - * avoid new buffers getting queued and then wait for all the current - * buffers to finish. - */ - pipe->stopping = true; - mutex_unlock(&isp->mutex); - /* wait max 1 second */ - ret = wait_event_timeout(pipe->vb_queue.done_wq, - atomisp_buffers_in_css(pipe) == 0, HZ); - mutex_lock(&isp->mutex); - pipe->stopping = false; - if (ret == 0) - dev_warn(isp->dev, "Warning timeout waiting for CSS to return buffers\n"); - spin_lock_irqsave(&isp->lock, flags); asd->streaming = false; spin_unlock_irqrestore(&isp->lock, flags); @@ -890,8 +874,6 @@ static void atomisp_stop_stream(struct atomisp_video_pipe *pipe, atomisp_css_stop(asd, false); - atomisp_flush_video_pipe(pipe, state, true); - atomisp_subdev_cleanup_pending_events(asd); if (stop_sensor) { @@ -920,6 +902,8 @@ static void atomisp_stop_stream(struct atomisp_video_pipe *pipe, isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK); atomisp_reset(isp); + atomisp_flush_video_pipe(pipe, state, false); + /* Streams were destroyed by atomisp_css_stop(), recreate them. */ ret = atomisp_create_pipes_stream(&isp->asd); if (ret) diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.h b/drivers/staging/media/atomisp/pci/atomisp_subdev.h index bd1a198cda30..e1d0168cb91d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.h +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.h @@ -57,9 +57,6 @@ struct atomisp_video_pipe { /* Filled through atomisp_get_css_frame_info() on queue setup */ struct ia_css_frame_info frame_info; - /* Set from streamoff to disallow queuing further buffers in CSS */ - bool stopping; - /* * irq_lock is used to protect video buffer state change operations and * also to make activeq and capq operations atomic.