1 From 0df32e2f563123166c20677f022d4a0f825c5df2 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Fri, 15 Feb 2019 11:38:45 +0000
4 Subject: [PATCH] staging: bcm2835_codec: Fix handling of
5 VB2_MEMORY_DMABUF buffers
7 If the queue is configured as VB2_MEMORY_DMABUF then vb2_core_expbuf
8 fails as it ensures the queue is defined as VB2_MEMORY_MMAP.
10 Correct the handling so that we unmap the buffer from vcsm and the
11 VPU on cleanup, and then correctly get the dma buf of the new buffer.
13 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
15 .../bcm2835-codec/bcm2835-v4l2-codec.c | 80 +++++++++++++------
16 .../vc04_services/vchiq-mmal/mmal-vchiq.c | 21 +++--
17 .../vc04_services/vchiq-mmal/mmal-vchiq.h | 2 +
18 3 files changed, 73 insertions(+), 30 deletions(-)
20 --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
21 +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
22 @@ -1852,6 +1852,18 @@ static int bcm2835_codec_queue_setup(str
26 +static int bcm2835_codec_mmal_buf_cleanup(struct mmal_buffer *mmal_buf)
28 + mmal_vchi_buffer_cleanup(mmal_buf);
30 + if (mmal_buf->dma_buf) {
31 + dma_buf_put(mmal_buf->dma_buf);
32 + mmal_buf->dma_buf = NULL;
38 static int bcm2835_codec_buf_init(struct vb2_buffer *vb)
40 struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
41 @@ -1880,6 +1892,7 @@ static int bcm2835_codec_buf_prepare(str
43 struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer,
45 + struct dma_buf *dma_buf;
48 v4l2_dbg(4, debug, &ctx->dev->v4l2_dev, "%s: type: %d ptr %p\n",
49 @@ -1906,20 +1919,48 @@ static int bcm2835_codec_buf_prepare(str
50 if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type))
51 vb2_set_plane_payload(vb, 0, q_data->sizeimage);
54 - * We want to do this at init, but vb2_core_expbuf checks that the
55 - * index < q->num_buffers, and q->num_buffers only gets updated once
56 - * all the buffers are allocated.
58 - if (!buf->mmal.dma_buf) {
59 - ret = vb2_core_expbuf_dmabuf(vb->vb2_queue,
60 - vb->vb2_queue->type, vb->index, 0,
61 - O_CLOEXEC, &buf->mmal.dma_buf);
63 - v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed to expbuf idx %d, ret %d\n",
64 - __func__, vb->index, ret);
66 + switch (vb->memory) {
67 + case VB2_MEMORY_DMABUF:
68 + dma_buf = dma_buf_get(vb->planes[0].m.fd);
70 + if (dma_buf != buf->mmal.dma_buf) {
71 + /* dmabuf either hasn't already been mapped, or it has
74 + if (buf->mmal.dma_buf) {
75 + v4l2_err(&ctx->dev->v4l2_dev,
76 + "%s Buffer changed - why did the core not call cleanup?\n",
78 + bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
81 + buf->mmal.dma_buf = dma_buf;
85 + case VB2_MEMORY_MMAP:
87 + * We want to do this at init, but vb2_core_expbuf checks that
88 + * the index < q->num_buffers, and q->num_buffers only gets
89 + * updated once all the buffers are allocated.
91 + if (!buf->mmal.dma_buf) {
92 + ret = vb2_core_expbuf_dmabuf(vb->vb2_queue,
93 + vb->vb2_queue->type,
96 + &buf->mmal.dma_buf);
98 + v4l2_err(&ctx->dev->v4l2_dev,
99 + "%s: Failed to expbuf idx %d, ret %d\n",
100 + __func__, vb->index, ret);
111 @@ -1948,12 +1989,7 @@ static void bcm2835_codec_buffer_cleanup
112 v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, vb %p\n",
115 - mmal_vchi_buffer_cleanup(&buf->mmal);
117 - if (buf->mmal.dma_buf) {
118 - dma_buf_put(buf->mmal.dma_buf);
119 - buf->mmal.dma_buf = NULL;
121 + bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
124 static int bcm2835_codec_start_streaming(struct vb2_queue *q,
125 @@ -2067,11 +2103,7 @@ static void bcm2835_codec_stop_streaming
126 m2m = container_of(vb2, struct v4l2_m2m_buffer, vb);
127 buf = container_of(m2m, struct m2m_mmal_buffer, m2m);
129 - mmal_vchi_buffer_cleanup(&buf->mmal);
130 - if (buf->mmal.dma_buf) {
131 - dma_buf_put(buf->mmal.dma_buf);
132 - buf->mmal.dma_buf = NULL;
134 + bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
137 /* If both ports disabled, then disable the component */
138 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
139 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
140 @@ -1785,13 +1785,9 @@ int mmal_vchi_buffer_init(struct vchiq_m
142 EXPORT_SYMBOL_GPL(mmal_vchi_buffer_init);
144 -int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
145 +int mmal_vchi_buffer_unmap(struct mmal_buffer *buf)
147 - struct mmal_msg_context *msg_context = buf->msg_context;
150 - release_msg_context(msg_context);
151 - buf->msg_context = NULL;
154 if (buf->vcsm_handle) {
156 @@ -1803,6 +1799,19 @@ int mmal_vchi_buffer_cleanup(struct mmal
157 pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret);
158 buf->vcsm_handle = 0;
162 +EXPORT_SYMBOL_GPL(mmal_vchi_buffer_unmap);
164 +int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
166 + struct mmal_msg_context *msg_context = buf->msg_context;
169 + release_msg_context(msg_context);
170 + buf->msg_context = NULL;
172 + mmal_vchi_buffer_unmap(buf);
175 EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
176 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
177 +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
178 @@ -167,6 +167,8 @@ int vchiq_mmal_submit_buffer(struct vchi
179 struct vchiq_mmal_port *port,
180 struct mmal_buffer *buf);
182 +int mmal_vchi_buffer_unmap(struct mmal_buffer *buf);
184 int mmal_vchi_buffer_init(struct vchiq_mmal_instance *instance,
185 struct mmal_buffer *buf);
186 int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf);