summaryrefslogtreecommitdiffstats
path: root/drivers/staging/vc04_services
diff options
context:
space:
mode:
authorDave Stevenson2019-06-29 14:13:29 +0200
committerGreg Kroah-Hartman2019-07-01 09:09:08 +0200
commit70ec64ccdaac5d8f634338e33b016c1c99831499 (patch)
tree15f147bf10e6561de6f5f09d27e441d511b7db06 /drivers/staging/vc04_services
parentstaging: bcm2835-camera: Fix open parenthesis alignment (diff)
downloadkernel-qcow2-linux-70ec64ccdaac5d8f634338e33b016c1c99831499.tar.gz
kernel-qcow2-linux-70ec64ccdaac5d8f634338e33b016c1c99831499.tar.xz
kernel-qcow2-linux-70ec64ccdaac5d8f634338e33b016c1c99831499.zip
staging: bcm2835-camera: Ensure all buffers are returned on disable
With the recent change to match MMAL and V4L2 buffers there is a need to wait for all MMAL buffers to be returned during stop_streaming. Fixes: 938416707071 ("staging: bcm2835-camera: Remove V4L2/MMAL buffer remapping") Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> Signed-off-by: Stefan Wahren <wahrenst@gmx.net> Acked-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/vc04_services')
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c22
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c4
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h3
3 files changed, 23 insertions, 6 deletions
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index 43499b5b6a6b..f2010655f58e 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -584,6 +584,7 @@ static void stop_streaming(struct vb2_queue *vq)
int ret;
unsigned long timeout;
struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
+ struct vchiq_mmal_port *port = dev->capture.port;
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n",
__func__, dev);
@@ -607,12 +608,6 @@ static void stop_streaming(struct vb2_queue *vq)
&dev->capture.frame_count,
sizeof(dev->capture.frame_count));
- /* wait for last frame to complete */
- timeout = wait_for_completion_timeout(&dev->capture.frame_cmplt, HZ);
- if (timeout == 0)
- v4l2_err(&dev->v4l2_dev,
- "timed out waiting for frame completion\n");
-
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
"disabling connection\n");
@@ -627,6 +622,21 @@ static void stop_streaming(struct vb2_queue *vq)
ret);
}
+ /* wait for all buffers to be returned */
+ while (atomic_read(&port->buffers_with_vpu)) {
+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+ "%s: Waiting for buffers to be returned - %d outstanding\n",
+ __func__, atomic_read(&port->buffers_with_vpu));
+ timeout = wait_for_completion_timeout(&dev->capture.frame_cmplt,
+ HZ);
+ if (timeout == 0) {
+ v4l2_err(&dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n",
+ __func__,
+ atomic_read(&port->buffers_with_vpu));
+ break;
+ }
+ }
+
if (disable_camera(dev) < 0)
v4l2_err(&dev->v4l2_dev, "Failed to disable camera\n");
}
diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
index 0b9572314a6e..4d6317639d43 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
@@ -246,6 +246,8 @@ static void buffer_work_cb(struct work_struct *work)
struct mmal_msg_context *msg_context =
container_of(work, struct mmal_msg_context, u.bulk.work);
+ atomic_dec(&msg_context->u.bulk.port->buffers_with_vpu);
+
msg_context->u.bulk.port->buffer_cb(msg_context->u.bulk.instance,
msg_context->u.bulk.port,
msg_context->u.bulk.status,
@@ -389,6 +391,8 @@ buffer_from_host(struct vchiq_mmal_instance *instance,
INIT_WORK(&msg_context->u.bulk.buffer_to_host_work,
buffer_to_host_work_cb);
+ atomic_inc(&port->buffers_with_vpu);
+
/* prep the buffer from host message */
memset(&m, 0xbc, sizeof(m)); /* just to make debug clearer */
diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h
index 3498555d5828..1750ff06164d 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h
+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h
@@ -72,6 +72,9 @@ struct vchiq_mmal_port {
struct list_head buffers;
/* lock to serialise adding and removing buffers from list */
spinlock_t slock;
+
+ /* Count of buffers the VPU has yet to return */
+ atomic_t buffers_with_vpu;
/* callback on buffer completion */
vchiq_mmal_buffer_cb buffer_cb;
/* callback context */