brcm2708: bcm2711: remove custom config file
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.19 / 950-0626-staging-vc-sm-cma-Add-in-userspace-allocation-API.patch
1 From b55553b491ccfb9fc7b9b3b399c4796bd802c812 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Mon, 11 Mar 2019 16:35:23 +0000
4 Subject: [PATCH 626/773] staging: vc-sm-cma: Add in userspace allocation API
5
6 Replacing the functionality from the older vc-sm driver,
7 add in a userspace API that allows allocation of buffers,
8 and importing of dma-bufs.
9 The driver hands out dma-buf fds, therefore much of the
10 handling around lifespan and odd mmaps from the old driver
11 goes away.
12
13 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
14 ---
15 .../staging/vc04_services/vc-sm-cma/vc_sm.c | 371 ++++++++++++++++--
16 .../vc04_services/vc-sm-cma/vc_sm_cma.c | 3 +-
17 .../vc04_services/vc-sm-cma/vc_sm_cma.h | 2 +-
18 include/linux/broadcom/vc_sm_cma_ioctl.h | 87 ++++
19 4 files changed, 435 insertions(+), 28 deletions(-)
20 create mode 100644 include/linux/broadcom/vc_sm_cma_ioctl.h
21
22 --- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c
23 +++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c
24 @@ -36,6 +36,7 @@
25 #include <linux/fs.h>
26 #include <linux/kernel.h>
27 #include <linux/list.h>
28 +#include <linux/miscdevice.h>
29 #include <linux/module.h>
30 #include <linux/mm.h>
31 #include <linux/of_device.h>
32 @@ -52,6 +53,7 @@
33 #include "vc_sm.h"
34 #include "vc_sm_cma.h"
35 #include "vc_sm_knl.h"
36 +#include <linux/broadcom/vc_sm_cma_ioctl.h>
37
38 /* ---- Private Constants and Types --------------------------------------- */
39
40 @@ -83,6 +85,8 @@ struct sm_pde_t {
41 struct sm_state_t {
42 struct platform_device *pdev;
43
44 + struct miscdevice misc_dev;
45 +
46 struct sm_instance *sm_handle; /* Handle for videocore service. */
47 struct cma *cma_heap;
48
49 @@ -346,7 +350,6 @@ static void vc_sm_release_resource(struc
50
51 defer:
52 mutex_unlock(&buffer->lock);
53 - return;
54 }
55
56 /* Create support for private data tracking. */
57 @@ -381,7 +384,7 @@ static struct sg_table *dup_sg_table(str
58 ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL);
59 if (ret) {
60 kfree(new_table);
61 - return ERR_PTR(-ENOMEM);
62 + return ERR_PTR(ret);
63 }
64
65 new_sg = new_table->sgl;
66 @@ -417,7 +420,7 @@ static int vc_sm_dma_buf_attach(struct d
67 table = dup_sg_table(buf->sg_table);
68 if (IS_ERR(table)) {
69 kfree(a);
70 - return -ENOMEM;
71 + return PTR_ERR(table);
72 }
73
74 a->table = table;
75 @@ -433,8 +436,8 @@ static int vc_sm_dma_buf_attach(struct d
76 return 0;
77 }
78
79 -static void vc_sm_dma_buf_detatch(struct dma_buf *dmabuf,
80 - struct dma_buf_attachment *attachment)
81 +static void vc_sm_dma_buf_detach(struct dma_buf *dmabuf,
82 + struct dma_buf_attachment *attachment)
83 {
84 struct vc_sm_dma_buf_attachment *a = attachment->priv;
85 struct vc_sm_buffer *buf = dmabuf->priv;
86 @@ -544,6 +547,9 @@ static void vc_sm_dma_buf_release(struct
87 vc_sm_clean_up_dmabuf(buffer);
88 pr_debug("%s clean_up dmabuf done\n", __func__);
89
90 + /* buffer->lock will be destroyed by vc_sm_release_resource if finished
91 + * with, otherwise unlocked. Do NOT unlock here.
92 + */
93 vc_sm_release_resource(buffer);
94 pr_debug("%s done\n", __func__);
95 }
96 @@ -613,7 +619,7 @@ static const struct dma_buf_ops dma_buf_
97 .mmap = vc_sm_dmabuf_mmap,
98 .release = vc_sm_dma_buf_release,
99 .attach = vc_sm_dma_buf_attach,
100 - .detach = vc_sm_dma_buf_detatch,
101 + .detach = vc_sm_dma_buf_detach,
102 .begin_cpu_access = vc_sm_dma_buf_begin_cpu_access,
103 .end_cpu_access = vc_sm_dma_buf_end_cpu_access,
104 .map = vc_sm_dma_buf_kmap,
105 @@ -762,6 +768,7 @@ static const struct dma_buf_ops dma_buf_
106 int
107 vc_sm_cma_import_dmabuf_internal(struct vc_sm_privdata_t *private,
108 struct dma_buf *dma_buf,
109 + int fd,
110 struct dma_buf **imported_buf)
111 {
112 DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
113 @@ -775,10 +782,15 @@ vc_sm_cma_import_dmabuf_internal(struct
114 int status;
115
116 /* Setup our allocation parameters */
117 - pr_debug("%s: importing dma_buf %p\n", __func__, dma_buf);
118 + pr_debug("%s: importing dma_buf %p/fd %d\n", __func__, dma_buf, fd);
119
120 - get_dma_buf(dma_buf);
121 - dma_buf = dma_buf;
122 + if (fd < 0)
123 + get_dma_buf(dma_buf);
124 + else
125 + dma_buf = dma_buf_get(fd);
126 +
127 + if (!dma_buf)
128 + return -EINVAL;
129
130 attach = dma_buf_attach(dma_buf, &sm_state->pdev->dev);
131 if (IS_ERR(attach)) {
132 @@ -921,6 +933,10 @@ static int vc_sm_cma_vpu_alloc(u32 size,
133 return -ENOMEM;
134
135 mutex_init(&buffer->lock);
136 + /* Acquire the mutex as vc_sm_release_resource will release it in the
137 + * error path.
138 + */
139 + mutex_lock(&buffer->lock);
140
141 if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc,
142 aligned_size)) {
143 @@ -976,6 +992,8 @@ static int vc_sm_cma_vpu_alloc(u32 size,
144
145 vc_sm_add_resource(sm_state->vpu_allocs, buffer);
146
147 + mutex_unlock(&buffer->lock);
148 +
149 *ret_buffer = buffer;
150 return 0;
151 error:
152 @@ -1065,6 +1083,297 @@ vc_sm_vpu_event(struct sm_instance *inst
153 }
154 }
155
156 +/* Userspace handling */
157 +/*
158 + * Open the device. Creates a private state to help track all allocation
159 + * associated with this device.
160 + */
161 +static int vc_sm_cma_open(struct inode *inode, struct file *file)
162 +{
163 + /* Make sure the device was started properly. */
164 + if (!sm_state) {
165 + pr_err("[%s]: invalid device\n", __func__);
166 + return -EPERM;
167 + }
168 +
169 + file->private_data = vc_sm_cma_create_priv_data(current->tgid);
170 + if (!file->private_data) {
171 + pr_err("[%s]: failed to create data tracker\n", __func__);
172 +
173 + return -ENOMEM;
174 + }
175 +
176 + return 0;
177 +}
178 +
179 +/*
180 + * Close the vcsm-cma device.
181 + * All allocations are file descriptors to the dmabuf objects, so we will get
182 + * the clean up request on those as those are cleaned up.
183 + */
184 +static int vc_sm_cma_release(struct inode *inode, struct file *file)
185 +{
186 + struct vc_sm_privdata_t *file_data =
187 + (struct vc_sm_privdata_t *)file->private_data;
188 + int ret = 0;
189 +
190 + /* Make sure the device was started properly. */
191 + if (!sm_state || !file_data) {
192 + pr_err("[%s]: invalid device\n", __func__);
193 + ret = -EPERM;
194 + goto out;
195 + }
196 +
197 + pr_debug("[%s]: using private data %p\n", __func__, file_data);
198 +
199 + /* Terminate the private data. */
200 + kfree(file_data);
201 +
202 +out:
203 + return ret;
204 +}
205 +
206 +/*
207 + * Allocate a shared memory handle and block.
208 + * Allocation is from CMA, and then imported into the VPU mappings.
209 + */
210 +int vc_sm_cma_ioctl_alloc(struct vc_sm_privdata_t *private,
211 + struct vc_sm_cma_ioctl_alloc *ioparam)
212 +{
213 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
214 + struct vc_sm_buffer *buffer = NULL;
215 + struct vc_sm_import import = { 0 };
216 + struct vc_sm_import_result result = { 0 };
217 + struct dma_buf *dmabuf = NULL;
218 + int aligned_size;
219 + int ret = 0;
220 + int status;
221 + int fd = -1;
222 +
223 + aligned_size = PAGE_ALIGN(ioparam->size);
224 +
225 + if (!aligned_size)
226 + return -EINVAL;
227 +
228 + /* Allocate local buffer to track this allocation. */
229 + buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
230 + if (!buffer) {
231 + ret = -ENOMEM;
232 + goto error;
233 + }
234 +
235 + if (vc_sm_cma_buffer_allocate(sm_state->cma_heap, &buffer->alloc,
236 + aligned_size)) {
237 + pr_err("[%s]: cma alloc of %d bytes failed\n",
238 + __func__, aligned_size);
239 + kfree(buffer);
240 + return -ENOMEM;
241 + }
242 + buffer->sg_table = buffer->alloc.sg_table;
243 +
244 + if (dma_map_sg(&sm_state->pdev->dev, buffer->sg_table->sgl,
245 + buffer->sg_table->nents, DMA_BIDIRECTIONAL) <= 0) {
246 + pr_err("[%s]: dma_map_sg failed\n", __func__);
247 + ret = -ENOMEM;
248 + goto error;
249 + }
250 +
251 + import.type = VC_SM_ALLOC_NON_CACHED;
252 + import.allocator = current->tgid;
253 +
254 + if (*ioparam->name)
255 + memcpy(import.name, ioparam->name, sizeof(import.name) - 1);
256 + else
257 + memcpy(import.name, VC_SM_RESOURCE_NAME_DEFAULT,
258 + sizeof(VC_SM_RESOURCE_NAME_DEFAULT));
259 +
260 + mutex_init(&buffer->lock);
261 + INIT_LIST_HEAD(&buffer->attachments);
262 + memcpy(buffer->name, import.name,
263 + min(sizeof(buffer->name), sizeof(import.name) - 1));
264 +
265 + exp_info.ops = &dma_buf_ops;
266 + exp_info.size = aligned_size;
267 + exp_info.flags = O_RDWR;
268 + exp_info.priv = buffer;
269 +
270 + dmabuf = dma_buf_export(&exp_info);
271 + if (IS_ERR(dmabuf)) {
272 + ret = PTR_ERR(dmabuf);
273 + goto error;
274 + }
275 + buffer->dma_buf = dmabuf;
276 +
277 + import.addr = (uint32_t)sg_dma_address(buffer->sg_table->sgl);
278 + import.size = aligned_size;
279 + import.kernel_id = (uint32_t)buffer;
280 +
281 + /* Wrap it into a videocore buffer. */
282 + status = vc_sm_cma_vchi_import(sm_state->sm_handle, &import, &result,
283 + &sm_state->int_trans_id);
284 + if (status == -EINTR) {
285 + pr_debug("[%s]: requesting import memory action restart (trans_id: %u)\n",
286 + __func__, sm_state->int_trans_id);
287 + ret = -ERESTARTSYS;
288 + private->restart_sys = -EINTR;
289 + private->int_action = VC_SM_MSG_TYPE_IMPORT;
290 + goto error;
291 + } else if (status || !result.res_handle) {
292 + pr_err("[%s]: failed to import memory on videocore (status: %u, trans_id: %u)\n",
293 + __func__, status, sm_state->int_trans_id);
294 + ret = -ENOMEM;
295 + goto error;
296 + }
297 +
298 + /* Keep track of the buffer we created. */
299 + buffer->private = private;
300 + buffer->vc_handle = result.res_handle;
301 + buffer->size = import.size;
302 + buffer->dma_addr = import.addr;
303 + buffer->vpu_state = VPU_MAPPED;
304 + //buffer->res_cached = ioparam->cached;
305 +
306 + fd = dma_buf_fd(dmabuf, O_CLOEXEC);
307 + if (fd < 0)
308 + goto error;
309 +
310 + vc_sm_add_resource(private, buffer);
311 +
312 + pr_debug("[%s]: Added resource as fd %d, buffer %p, private %p, dma_addr %pad\n",
313 + __func__, fd, buffer, private, &buffer->dma_addr);
314 +
315 + /* We're done */
316 + ioparam->handle = fd;
317 + ioparam->vc_handle = buffer->vc_handle;
318 + ioparam->dma_addr = buffer->dma_addr;
319 + return 0;
320 +
321 +error:
322 + if (buffer) {
323 + pr_err("[%s]: something failed - cleanup. ret %d\n", __func__,
324 + ret);
325 +
326 + dma_buf_put(dmabuf);
327 + }
328 + return ret;
329 +}
330 +
331 +static long vc_sm_cma_ioctl(struct file *file, unsigned int cmd,
332 + unsigned long arg)
333 +{
334 + int ret = 0;
335 + unsigned int cmdnr = _IOC_NR(cmd);
336 + struct vc_sm_privdata_t *file_data =
337 + (struct vc_sm_privdata_t *)file->private_data;
338 +
339 + /* Validate we can work with this device. */
340 + if (!sm_state || !file_data) {
341 + pr_err("[%s]: invalid device\n", __func__);
342 + return -EPERM;
343 + }
344 +
345 + pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr,
346 + current->tgid, file_data->pid);
347 +
348 + /* Action is a re-post of a previously interrupted action? */
349 + if (file_data->restart_sys == -EINTR) {
350 + struct vc_sm_action_clean_t action_clean;
351 +
352 + pr_debug("[%s]: clean up of action %u (trans_id: %u) following EINTR\n",
353 + __func__, file_data->int_action,
354 + file_data->int_trans_id);
355 +
356 + action_clean.res_action = file_data->int_action;
357 + action_clean.action_trans_id = file_data->int_trans_id;
358 +
359 + file_data->restart_sys = 0;
360 + }
361 +
362 + /* Now process the command. */
363 + switch (cmdnr) {
364 + /* New memory allocation.
365 + */
366 + case VC_SM_CMA_CMD_ALLOC:
367 + {
368 + struct vc_sm_cma_ioctl_alloc ioparam;
369 +
370 + /* Get the parameter data. */
371 + if (copy_from_user
372 + (&ioparam, (void *)arg, sizeof(ioparam)) != 0) {
373 + pr_err("[%s]: failed to copy-from-user for cmd %x\n",
374 + __func__, cmdnr);
375 + ret = -EFAULT;
376 + break;
377 + }
378 +
379 + ret = vc_sm_cma_ioctl_alloc(file_data, &ioparam);
380 + if (!ret &&
381 + (copy_to_user((void *)arg, &ioparam,
382 + sizeof(ioparam)) != 0)) {
383 + /* FIXME: Release allocation */
384 + pr_err("[%s]: failed to copy-to-user for cmd %x\n",
385 + __func__, cmdnr);
386 + ret = -EFAULT;
387 + }
388 + break;
389 + }
390 +
391 + case VC_SM_CMA_CMD_IMPORT_DMABUF:
392 + {
393 + struct vc_sm_cma_ioctl_import_dmabuf ioparam;
394 + struct dma_buf *new_dmabuf;
395 +
396 + /* Get the parameter data. */
397 + if (copy_from_user
398 + (&ioparam, (void *)arg, sizeof(ioparam)) != 0) {
399 + pr_err("[%s]: failed to copy-from-user for cmd %x\n",
400 + __func__, cmdnr);
401 + ret = -EFAULT;
402 + break;
403 + }
404 +
405 + ret = vc_sm_cma_import_dmabuf_internal(file_data,
406 + NULL,
407 + ioparam.dmabuf_fd,
408 + &new_dmabuf);
409 +
410 + if (!ret) {
411 + struct vc_sm_buffer *buf = new_dmabuf->priv;
412 +
413 + ioparam.size = buf->size;
414 + ioparam.handle = dma_buf_fd(new_dmabuf,
415 + O_CLOEXEC);
416 + ioparam.vc_handle = buf->vc_handle;
417 + ioparam.dma_addr = buf->dma_addr;
418 +
419 + if (ioparam.handle < 0 ||
420 + (copy_to_user((void *)arg, &ioparam,
421 + sizeof(ioparam)) != 0)) {
422 + dma_buf_put(new_dmabuf);
423 + /* FIXME: Release allocation */
424 + ret = -EFAULT;
425 + }
426 + }
427 + break;
428 + }
429 +
430 + default:
431 + ret = -EINVAL;
432 + break;
433 + }
434 +
435 + return ret;
436 +}
437 +
438 +/* Device operations that we managed in this driver. */
439 +static const struct file_operations vc_sm_ops = {
440 + .owner = THIS_MODULE,
441 + .unlocked_ioctl = vc_sm_cma_ioctl,
442 + .open = vc_sm_cma_open,
443 + .release = vc_sm_cma_release,
444 +};
445 +
446 +/* Driver load/unload functions */
447 /* Videocore connected. */
448 static void vc_sm_connected_init(void)
449 {
450 @@ -1075,12 +1384,11 @@ static void vc_sm_connected_init(void)
451
452 pr_info("[%s]: start\n", __func__);
453
454 - if (vc_sm_cma_add_heaps(&sm_state->cma_heap) ||
455 - !sm_state->cma_heap) {
456 - pr_err("[%s]: failed to initialise CMA heaps\n",
457 + vc_sm_cma_add_heaps(&sm_state->cma_heap);
458 + if (!sm_state->cma_heap) {
459 + pr_err("[%s]: failed to initialise CMA heap\n",
460 __func__);
461 - ret = -EIO;
462 - goto err_free_mem;
463 + return;
464 }
465
466 /*
467 @@ -1092,8 +1400,7 @@ static void vc_sm_connected_init(void)
468 pr_err("[%s]: failed to initialise VCHI instance (ret=%d)\n",
469 __func__, ret);
470
471 - ret = -EIO;
472 - goto err_failed;
473 + return;
474 }
475
476 ret = vchi_connect(NULL, 0, vchi_instance);
477 @@ -1101,8 +1408,7 @@ static void vc_sm_connected_init(void)
478 pr_err("[%s]: failed to connect VCHI instance (ret=%d)\n",
479 __func__, ret);
480
481 - ret = -EIO;
482 - goto err_failed;
483 + return;
484 }
485
486 /* Initialize an instance of the shared memory service. */
487 @@ -1112,8 +1418,7 @@ static void vc_sm_connected_init(void)
488 pr_err("[%s]: failed to initialize shared memory service\n",
489 __func__);
490
491 - ret = -EPERM;
492 - goto err_failed;
493 + return;
494 }
495
496 /* Create a debug fs directory entry (root). */
497 @@ -1127,11 +1432,22 @@ static void vc_sm_connected_init(void)
498
499 INIT_LIST_HEAD(&sm_state->buffer_list);
500
501 + /* Create a shared memory device. */
502 + sm_state->misc_dev.minor = MISC_DYNAMIC_MINOR;
503 + sm_state->misc_dev.name = DEVICE_NAME;
504 + sm_state->misc_dev.fops = &vc_sm_ops;
505 + sm_state->misc_dev.parent = NULL;
506 + ret = misc_register(&sm_state->misc_dev);
507 + if (ret) {
508 + pr_err("vcsm-cma: failed to register misc device.\n");
509 + goto err_remove_debugfs;
510 + }
511 +
512 sm_state->data_knl = vc_sm_cma_create_priv_data(0);
513 if (!sm_state->data_knl) {
514 pr_err("[%s]: failed to create kernel private data tracker\n",
515 __func__);
516 - goto err_remove_shared_memory;
517 + goto err_remove_misc_dev;
518 }
519
520 version.version = 2;
521 @@ -1148,11 +1464,13 @@ static void vc_sm_connected_init(void)
522 pr_info("[%s]: installed successfully\n", __func__);
523 return;
524
525 -err_remove_shared_memory:
526 +err_remove_misc_dev:
527 + misc_deregister(&sm_state->misc_dev);
528 +err_remove_debugfs:
529 debugfs_remove_recursive(sm_state->dir_root);
530 vc_sm_cma_vchi_stop(&sm_state->sm_handle);
531 -err_failed:
532 - pr_info("[%s]: failed, ret %d\n", __func__, ret);
533 +
534 + return;
535 }
536
537 /* Driver loading. */
538 @@ -1184,6 +1502,8 @@ static int bcm2835_vc_sm_cma_remove(stru
539 {
540 pr_debug("[%s]: start\n", __func__);
541 if (sm_inited) {
542 + misc_deregister(&sm_state->misc_dev);
543 +
544 /* Remove all proc entries. */
545 debugfs_remove_recursive(sm_state->dir_root);
546
547 @@ -1202,6 +1522,7 @@ static int bcm2835_vc_sm_cma_remove(stru
548 return 0;
549 }
550
551 +/* Kernel API calls */
552 /* Get an internal resource handle mapped from the external one. */
553 int vc_sm_cma_int_handle(void *handle)
554 {
555 @@ -1252,7 +1573,7 @@ int vc_sm_cma_import_dmabuf(struct dma_b
556 }
557
558 ret = vc_sm_cma_import_dmabuf_internal(sm_state->data_knl, src_dmabuf,
559 - &new_dma_buf);
560 + -1, &new_dma_buf);
561
562 if (!ret) {
563 pr_debug("%s: imported to ptr %p\n", __func__, new_dma_buf);
564 --- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c
565 +++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.c
566 @@ -92,8 +92,7 @@ int __vc_sm_cma_add_heaps(struct cma *cm
567 return 0;
568 }
569
570 -int vc_sm_cma_add_heaps(struct cma **cma_heap)
571 +void vc_sm_cma_add_heaps(struct cma **cma_heap)
572 {
573 cma_for_each_area(__vc_sm_cma_add_heaps, cma_heap);
574 - return 0;
575 }
576 --- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h
577 +++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm_cma.h
578 @@ -34,6 +34,6 @@ int vc_sm_cma_buffer_allocate(struct cma
579 unsigned long len);
580 void vc_sm_cma_buffer_free(struct vc_sm_cma_alloc_data *buffer);
581
582 -int vc_sm_cma_add_heaps(struct cma **cma_heap);
583 +void vc_sm_cma_add_heaps(struct cma **cma_heap);
584
585 #endif
586 --- /dev/null
587 +++ b/include/linux/broadcom/vc_sm_cma_ioctl.h
588 @@ -0,0 +1,87 @@
589 +/* SPDX-License-Identifier: GPL-2.0 */
590 +
591 +/*
592 + * Copyright 2019 Raspberry Pi (Trading) Ltd. All rights reserved.
593 + *
594 + * Based on vmcs_sm_ioctl.h Copyright Broadcom Corporation.
595 + */
596 +
597 +#ifndef __VC_SM_CMA_IOCTL_H
598 +#define __VC_SM_CMA_IOCTL_H
599 +
600 +/* ---- Include Files ---------------------------------------------------- */
601 +
602 +#if defined(__KERNEL__)
603 +#include <linux/types.h> /* Needed for standard types */
604 +#else
605 +#include <stdint.h>
606 +#endif
607 +
608 +#include <linux/ioctl.h>
609 +
610 +/* ---- Constants and Types ---------------------------------------------- */
611 +
612 +#define VC_SM_CMA_RESOURCE_NAME 32
613 +#define VC_SM_CMA_RESOURCE_NAME_DEFAULT "sm-host-resource"
614 +
615 +/* Type define used to create unique IOCTL number */
616 +#define VC_SM_CMA_MAGIC_TYPE 'J'
617 +
618 +/* IOCTL commands on /dev/vc-sm-cma */
619 +enum vc_sm_cma_cmd_e {
620 + VC_SM_CMA_CMD_ALLOC = 0x5A, /* Start at 0x5A arbitrarily */
621 +
622 + VC_SM_CMA_CMD_IMPORT_DMABUF,
623 +
624 + VC_SM_CMA_CMD_LAST /* Do not delete */
625 +};
626 +
627 +/* Cache type supported, conveniently matches the user space definition in
628 + * user-vcsm.h.
629 + */
630 +enum vc_sm_cma_cache_e {
631 + VC_SM_CMA_CACHE_NONE,
632 + VC_SM_CMA_CACHE_HOST,
633 + VC_SM_CMA_CACHE_VC,
634 + VC_SM_CMA_CACHE_BOTH,
635 +};
636 +
637 +/* IOCTL Data structures */
638 +struct vc_sm_cma_ioctl_alloc {
639 + /* user -> kernel */
640 + __u32 size;
641 + __u32 num;
642 + __u32 cached; /* enum vc_sm_cma_cache_e */
643 + __u32 pad;
644 + __u8 name[VC_SM_CMA_RESOURCE_NAME];
645 +
646 + /* kernel -> user */
647 + __s32 handle;
648 + __u32 vc_handle;
649 + __u64 dma_addr;
650 +};
651 +
652 +struct vc_sm_cma_ioctl_import_dmabuf {
653 + /* user -> kernel */
654 + __s32 dmabuf_fd;
655 + __u32 cached; /* enum vc_sm_cma_cache_e */
656 + __u8 name[VC_SM_CMA_RESOURCE_NAME];
657 +
658 + /* kernel -> user */
659 + __s32 handle;
660 + __u32 vc_handle;
661 + __u32 size;
662 + __u32 pad;
663 + __u64 dma_addr;
664 +};
665 +
666 +/* IOCTL numbers */
667 +#define VC_SM_CMA_IOCTL_MEM_ALLOC\
668 + _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_ALLOC,\
669 + struct vc_sm_cma_ioctl_alloc)
670 +
671 +#define VC_SM_CMA_IOCTL_MEM_IMPORT_DMABUF\
672 + _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_IMPORT_DMABUF,\
673 + struct vc_sm_cma_ioctl_import_dmabuf)
674 +
675 +#endif /* __VC_SM_CMA_IOCTL_H */