Commit 96b7e81a authored by Dave Stevenson's avatar Dave Stevenson Committed by Greg Kroah-Hartman

staging: bcm2835-camera: Allocate context once per buffer

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: default avatarDave Stevenson <dave.stevenson@raspberrypi.org>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent dd9bb505
...@@ -278,6 +278,20 @@ static int queue_setup(struct vb2_queue *vq, ...@@ -278,6 +278,20 @@ static int queue_setup(struct vb2_queue *vq,
return 0; 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) static int buffer_prepare(struct vb2_buffer *vb)
{ {
struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue); struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
...@@ -300,6 +314,17 @@ static int buffer_prepare(struct vb2_buffer *vb) ...@@ -300,6 +314,17 @@ static int buffer_prepare(struct vb2_buffer *vb)
return 0; 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) static inline bool is_capturing(struct bm2835_mmal_dev *dev)
{ {
return dev->capture.camera_port == return dev->capture.camera_port ==
...@@ -467,9 +492,6 @@ static void buffer_queue(struct vb2_buffer *vb) ...@@ -467,9 +492,6 @@ static void buffer_queue(struct vb2_buffer *vb)
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
"%s: dev:%p buf:%p\n", __func__, dev, buf); "%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); ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port, buf);
if (ret < 0) if (ret < 0)
v4l2_err(&dev->v4l2_dev, "%s: error submitting buffer\n", v4l2_err(&dev->v4l2_dev, "%s: error submitting buffer\n",
...@@ -632,7 +654,9 @@ static void bm2835_mmal_unlock(struct vb2_queue *vq) ...@@ -632,7 +654,9 @@ static void bm2835_mmal_unlock(struct vb2_queue *vq)
static const struct vb2_ops bm2835_mmal_video_qops = { static const struct vb2_ops bm2835_mmal_video_qops = {
.queue_setup = queue_setup, .queue_setup = queue_setup,
.buf_init = buffer_init,
.buf_prepare = buffer_prepare, .buf_prepare = buffer_prepare,
.buf_cleanup = buffer_cleanup,
.buf_queue = buffer_queue, .buf_queue = buffer_queue,
.start_streaming = start_streaming, .start_streaming = start_streaming,
.stop_streaming = stop_streaming, .stop_streaming = stop_streaming,
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
/** Special value signalling that time is not known */ /** Special value signalling that time is not known */
#define MMAL_TIME_UNKNOWN (1LL<<63) #define MMAL_TIME_UNKNOWN (1LL<<63)
struct mmal_msg_context;
/* mapping between v4l and mmal video modes */ /* mapping between v4l and mmal video modes */
struct mmal_fmt { struct mmal_fmt {
char *name; char *name;
...@@ -43,6 +45,8 @@ struct mmal_buffer { ...@@ -43,6 +45,8 @@ struct mmal_buffer {
void *buffer; /* buffer pointer */ void *buffer; /* buffer pointer */
unsigned long buffer_size; /* size of allocated buffer */ unsigned long buffer_size; /* size of allocated buffer */
struct mmal_msg_context *msg_context;
}; };
/* */ /* */
......
...@@ -321,8 +321,6 @@ static void buffer_work_cb(struct work_struct *work) ...@@ -321,8 +321,6 @@ static void buffer_work_cb(struct work_struct *work)
msg_context->u.bulk.dts, msg_context->u.bulk.dts,
msg_context->u.bulk.pts); msg_context->u.bulk.pts);
/* release message context */
release_msg_context(msg_context);
} }
/* enqueue a bulk receive for a given message context */ /* enqueue a bulk receive for a given message context */
...@@ -503,11 +501,13 @@ buffer_from_host(struct vchiq_mmal_instance *instance, ...@@ -503,11 +501,13 @@ buffer_from_host(struct vchiq_mmal_instance *instance,
return -EINTR; return -EINTR;
/* get context */ /* get context */
msg_context = get_msg_context(instance); if (!buf->msg_context) {
if (IS_ERR(msg_context)) { pr_err("%s: msg_context not allocated, buf %p\n", __func__,
ret = PTR_ERR(msg_context); buf);
ret = -EINVAL;
goto unlock; goto unlock;
} }
msg_context = buf->msg_context;
/* store bulk message context for when data arrives */ /* store bulk message context for when data arrives */
msg_context->u.bulk.instance = instance; msg_context->u.bulk.instance = instance;
...@@ -557,11 +557,6 @@ buffer_from_host(struct vchiq_mmal_instance *instance, ...@@ -557,11 +557,6 @@ buffer_from_host(struct vchiq_mmal_instance *instance,
sizeof(struct mmal_msg_header) + sizeof(struct mmal_msg_header) +
sizeof(m.u.buffer_from_host)); 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); vchi_service_release(instance->handle);
unlock: unlock:
...@@ -1775,6 +1770,29 @@ int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, ...@@ -1775,6 +1770,29 @@ int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance,
return 0; 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 /* Initialise a mmal component and its ports
* *
*/ */
......
...@@ -168,4 +168,7 @@ int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance, ...@@ -168,4 +168,7 @@ int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance,
struct vchiq_mmal_port *port, struct vchiq_mmal_port *port,
struct mmal_buffer *buf); 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 */ #endif /* MMAL_VCHIQ_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment