f2aeb91620f02d5ef26babe1114417e8d1b83760
[openwrt/staging/981213.git] /
1 From 5dce6c2a033e210ceead1b9ae756905246ae5082 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
6
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.
9
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.
12
13 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
14 ---
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(-)
19
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
23 return 0;
24 }
25
26 +static int bcm2835_codec_mmal_buf_cleanup(struct mmal_buffer *mmal_buf)
27 +{
28 + mmal_vchi_buffer_cleanup(mmal_buf);
29 +
30 + if (mmal_buf->dma_buf) {
31 + dma_buf_put(mmal_buf->dma_buf);
32 + mmal_buf->dma_buf = NULL;
33 + }
34 +
35 + return 0;
36 +}
37 +
38 static int bcm2835_codec_buf_init(struct vb2_buffer *vb)
39 {
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
42 vb);
43 struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer,
44 m2m);
45 + struct dma_buf *dma_buf;
46 int ret;
47
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);
52
53 - /*
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.
57 - */
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);
62 - if (ret)
63 - v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed to expbuf idx %d, ret %d\n",
64 - __func__, vb->index, ret);
65 - } else {
66 + switch (vb->memory) {
67 + case VB2_MEMORY_DMABUF:
68 + dma_buf = dma_buf_get(vb->planes[0].m.fd);
69 +
70 + if (dma_buf != buf->mmal.dma_buf) {
71 + /* dmabuf either hasn't already been mapped, or it has
72 + * changed.
73 + */
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",
77 + __func__);
78 + bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
79 + }
80 +
81 + buf->mmal.dma_buf = dma_buf;
82 + }
83 ret = 0;
84 + break;
85 + case VB2_MEMORY_MMAP:
86 + /*
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.
90 + */
91 + if (!buf->mmal.dma_buf) {
92 + ret = vb2_core_expbuf_dmabuf(vb->vb2_queue,
93 + vb->vb2_queue->type,
94 + vb->index, 0,
95 + O_CLOEXEC,
96 + &buf->mmal.dma_buf);
97 + if (ret)
98 + v4l2_err(&ctx->dev->v4l2_dev,
99 + "%s: Failed to expbuf idx %d, ret %d\n",
100 + __func__, vb->index, ret);
101 + } else {
102 + ret = 0;
103 + }
104 + break;
105 + default:
106 + ret = -EINVAL;
107 + break;
108 }
109
110 return 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",
113 __func__, ctx, vb);
114
115 - mmal_vchi_buffer_cleanup(&buf->mmal);
116 -
117 - if (buf->mmal.dma_buf) {
118 - dma_buf_put(buf->mmal.dma_buf);
119 - buf->mmal.dma_buf = NULL;
120 - }
121 + bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
122 }
123
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);
128
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;
133 - }
134 + bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
135 }
136
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 @@ -1784,13 +1784,9 @@ int mmal_vchi_buffer_init(struct vchiq_m
141 }
142 EXPORT_SYMBOL_GPL(mmal_vchi_buffer_init);
143
144 -int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
145 +int mmal_vchi_buffer_unmap(struct mmal_buffer *buf)
146 {
147 - struct mmal_msg_context *msg_context = buf->msg_context;
148 -
149 - if (msg_context)
150 - release_msg_context(msg_context);
151 - buf->msg_context = NULL;
152 + int ret = 0;
153
154 if (buf->vcsm_handle) {
155 int ret;
156 @@ -1802,6 +1798,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;
159 }
160 + return ret;
161 +}
162 +EXPORT_SYMBOL_GPL(mmal_vchi_buffer_unmap);
163 +
164 +int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
165 +{
166 + struct mmal_msg_context *msg_context = buf->msg_context;
167 +
168 + if (msg_context)
169 + release_msg_context(msg_context);
170 + buf->msg_context = NULL;
171 +
172 + mmal_vchi_buffer_unmap(buf);
173 return 0;
174 }
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);
181
182 +int mmal_vchi_buffer_unmap(struct mmal_buffer *buf);
183 +
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);