There is no guarantee that when we stop the pipeline all buffers owned
by the CSS are cleanly returned to the videobuf queue.
This is a problem with videobuf2 which will complain loudly when not
all buffers have been returned after the streamoff() queue op has
returned.
And this also allows moving a WARN() in the continuous mode path.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
.../staging/media/atomisp/pci/atomisp_fops.c | 3 ++
.../staging/media/atomisp/pci/atomisp_ioctl.c | 39 ++++++++-----------
.../media/atomisp/pci/atomisp_subdev.h | 3 +-
3 files changed, 21 insertions(+), 24 deletions(-)
@@ -222,6 +222,9 @@ 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;
+
while (pipe->buffers_in_css < ATOMISP_CSS_Q_DEPTH) {
struct videobuf_buffer *vb;
@@ -1754,6 +1754,22 @@ int atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
return -EINVAL;
}
+ /*
+ * 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_interruptible_timeout(pipe->capq.wait,
+ pipe->buffers_in_css == 0, HZ);
+ mutex_lock(&isp->mutex);
+ pipe->stopping = false;
+ if (ret <= 0)
+ return ret ? ret : -ETIME;
+
/*
* do only videobuf_streamoff for capture & vf pipes in
* case of continuous capture
@@ -1768,29 +1784,6 @@ int atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
0, 0, 0);
atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, false);
}
- /*
- * Currently there is no way to flush buffers queued to css.
- * When doing videobuf_streamoff, active buffers will be
- * marked as VIDEOBUF_NEEDS_INIT. HAL will be able to use
- * these buffers again, and these buffers might be queued to
- * css more than once! Warn here, if HAL has not dequeued all
- * buffers back before calling streamoff.
- */
- if (pipe->buffers_in_css != 0) {
- WARN(1, "%s: buffers of vdev %s still in CSS!\n",
- __func__, pipe->vdev.name);
-
- /*
- * Buffers remained in css maybe dequeued out in the
- * next stream on, while this will causes serious
- * issues as buffers already get invalid after
- * previous stream off.
- *
- * No way to flush buffers but to reset the whole css
- */
- dev_warn(isp->dev, "Reset CSS to clean up css buffers.\n");
- atomisp_css_flush(isp);
- }
return videobuf_streamoff(&pipe->capq);
}
@@ -81,7 +81,8 @@ struct atomisp_video_pipe {
/* Store here the initial run mode */
unsigned int default_run_mode;
-
+ /* Set from streamoff to disallow queuing further buffers in CSS */
+ bool stopping;
unsigned int buffers_in_css;
/*