You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
6.1 KiB
192 lines
6.1 KiB
From f36097b9766ff3f61c21d1fd29e75ddd3844a533 Mon Sep 17 00:00:00 2001
|
|
From: Dave Stevenson <dave.stevenson@raspberrypi.org>
|
|
Date: Thu, 10 May 2018 12:42:08 -0700
|
|
Subject: [PATCH 368/454] staging: bcm2835-camera: Allocate context once per
|
|
buffer
|
|
|
|
commit 96b7e81ab6b74e7cefdac0d7a90b746ef7f8597d upstream.
|
|
|
|
The struct mmal_msg_context was being allocated for every message
|
|
being sent to the VPU, and freed when it came back. Whilst that is
|
|
required behaviour for some messages (mainly the synchronous ones), it
|
|
is wasteful for the video buffers that make up the majority of the
|
|
traffic.
|
|
|
|
Add to the buffer_init/cleanup hooks that it allocates/frees the
|
|
msg_context required.
|
|
|
|
v2: changes by anholt from the downstream tree: clean up indentation,
|
|
pass an error value through, forward-declare the struct so we have
|
|
less void *
|
|
|
|
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
|
|
Signed-off-by: Eric Anholt <eric@anholt.net>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
.../bcm2835-camera/bcm2835-camera.c | 30 +++++++++++++--
|
|
.../bcm2835-camera/mmal-common.h | 4 ++
|
|
.../vc04_services/bcm2835-camera/mmal-vchiq.c | 38 ++++++++++++++-----
|
|
.../vc04_services/bcm2835-camera/mmal-vchiq.h | 3 ++
|
|
4 files changed, 62 insertions(+), 13 deletions(-)
|
|
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
|
|
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
|
|
@@ -280,6 +280,20 @@ static int queue_setup(struct vb2_queue
|
|
return 0;
|
|
}
|
|
|
|
+static int buffer_init(struct vb2_buffer *vb)
|
|
+{
|
|
+ struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
|
+ struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
|
|
+ struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb);
|
|
+
|
|
+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n",
|
|
+ __func__, dev, vb);
|
|
+ buf->buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
|
|
+ buf->buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0);
|
|
+
|
|
+ return mmal_vchi_buffer_init(dev->instance, buf);
|
|
+}
|
|
+
|
|
static int buffer_prepare(struct vb2_buffer *vb)
|
|
{
|
|
struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
|
@@ -302,6 +316,17 @@ static int buffer_prepare(struct vb2_buf
|
|
return 0;
|
|
}
|
|
|
|
+static void buffer_cleanup(struct vb2_buffer *vb)
|
|
+{
|
|
+ struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
|
+ struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
|
|
+ struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb);
|
|
+
|
|
+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n",
|
|
+ __func__, dev, vb);
|
|
+ mmal_vchi_buffer_cleanup(buf);
|
|
+}
|
|
+
|
|
static inline bool is_capturing(struct bm2835_mmal_dev *dev)
|
|
{
|
|
return dev->capture.camera_port ==
|
|
@@ -497,9 +522,6 @@ static void buffer_queue(struct vb2_buff
|
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
|
"%s: dev:%p buf:%p\n", __func__, dev, buf);
|
|
|
|
- buf->buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
|
|
- buf->buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0);
|
|
-
|
|
ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port, buf);
|
|
if (ret < 0)
|
|
v4l2_err(&dev->v4l2_dev, "%s: error submitting buffer\n",
|
|
@@ -665,7 +687,9 @@ static void bm2835_mmal_unlock(struct vb
|
|
|
|
static const struct vb2_ops bm2835_mmal_video_qops = {
|
|
.queue_setup = queue_setup,
|
|
+ .buf_init = buffer_init,
|
|
.buf_prepare = buffer_prepare,
|
|
+ .buf_cleanup = buffer_cleanup,
|
|
.buf_queue = buffer_queue,
|
|
.start_streaming = start_streaming,
|
|
.stop_streaming = stop_streaming,
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h
|
|
+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h
|
|
@@ -22,6 +22,8 @@
|
|
/** Special value signalling that time is not known */
|
|
#define MMAL_TIME_UNKNOWN (1LL<<63)
|
|
|
|
+struct mmal_msg_context;
|
|
+
|
|
/* mapping between v4l and mmal video modes */
|
|
struct mmal_fmt {
|
|
char *name;
|
|
@@ -46,6 +48,8 @@ struct mmal_buffer {
|
|
|
|
void *buffer; /* buffer pointer */
|
|
unsigned long buffer_size; /* size of allocated buffer */
|
|
+
|
|
+ struct mmal_msg_context *msg_context;
|
|
};
|
|
|
|
/* */
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
|
|
+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
|
|
@@ -324,8 +324,6 @@ static void buffer_work_cb(struct work_s
|
|
msg_context->u.bulk.dts,
|
|
msg_context->u.bulk.pts);
|
|
|
|
- /* release message context */
|
|
- release_msg_context(msg_context);
|
|
}
|
|
|
|
/* enqueue a bulk receive for a given message context */
|
|
@@ -506,11 +504,13 @@ buffer_from_host(struct vchiq_mmal_insta
|
|
return -EINTR;
|
|
|
|
/* get context */
|
|
- msg_context = get_msg_context(instance);
|
|
- if (IS_ERR(msg_context)) {
|
|
- ret = PTR_ERR(msg_context);
|
|
+ if (!buf->msg_context) {
|
|
+ pr_err("%s: msg_context not allocated, buf %p\n", __func__,
|
|
+ buf);
|
|
+ ret = -EINVAL;
|
|
goto unlock;
|
|
}
|
|
+ msg_context = buf->msg_context;
|
|
|
|
/* store bulk message context for when data arrives */
|
|
msg_context->u.bulk.instance = instance;
|
|
@@ -560,11 +560,6 @@ buffer_from_host(struct vchiq_mmal_insta
|
|
sizeof(struct mmal_msg_header) +
|
|
sizeof(m.u.buffer_from_host));
|
|
|
|
- if (ret != 0) {
|
|
- release_msg_context(msg_context);
|
|
- /* todo: is this correct error value? */
|
|
- }
|
|
-
|
|
vchi_service_release(instance->handle);
|
|
|
|
unlock:
|
|
@@ -1779,6 +1774,29 @@ int vchiq_mmal_submit_buffer(struct vchi
|
|
|
|
return 0;
|
|
}
|
|
+
|
|
+int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance,
|
|
+ struct mmal_buffer *buf)
|
|
+{
|
|
+ struct mmal_msg_context *msg_context = get_msg_context(instance);
|
|
+
|
|
+ if (IS_ERR(msg_context))
|
|
+ return (PTR_ERR(msg_context));
|
|
+
|
|
+ buf->msg_context = msg_context;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
|
|
+{
|
|
+ struct mmal_msg_context *msg_context = buf->msg_context;
|
|
+
|
|
+ if (msg_context)
|
|
+ release_msg_context(msg_context);
|
|
+ buf->msg_context = NULL;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
|
|
/* Initialise a mmal component and its ports
|
|
*
|
|
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h
|
|
+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h
|
|
@@ -171,4 +171,7 @@ int vchiq_mmal_submit_buffer(struct vchi
|
|
struct vchiq_mmal_port *port,
|
|
struct mmal_buffer *buf);
|
|
|
|
+int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance,
|
|
+ struct mmal_buffer *buf);
|
|
+int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf);
|
|
#endif /* MMAL_VCHIQ_H */
|
|
|