2 * videobuf2-dma-contig.c - DMA contig memory allocator for videobuf2
4 * Copyright (C) 2010 Samsung Electronics
6 * Author: Pawel Osciak <pawel@osciak.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation.
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/dma-mapping.h>
17 #include <media/videobuf2-core.h>
18 #include <media/videobuf2-dma-contig.h>
19 #include <media/videobuf2-memops.h>
26 struct vb2_dc_conf
*conf
;
30 struct vm_area_struct
*vma
;
32 struct vb2_vmarea_handler handler
;
35 static void vb2_dma_contig_put(void *buf_priv
);
37 static void *vb2_dma_contig_alloc(void *alloc_ctx
, unsigned long size
)
39 struct vb2_dc_conf
*conf
= alloc_ctx
;
40 struct vb2_dc_buf
*buf
;
42 buf
= kzalloc(sizeof *buf
, GFP_KERNEL
);
44 return ERR_PTR(-ENOMEM
);
46 buf
->vaddr
= dma_alloc_coherent(conf
->dev
, size
, &buf
->dma_addr
,
49 dev_err(conf
->dev
, "dma_alloc_coherent of size %ld failed\n",
52 return ERR_PTR(-ENOMEM
);
58 buf
->handler
.refcount
= &buf
->refcount
;
59 buf
->handler
.put
= vb2_dma_contig_put
;
60 buf
->handler
.arg
= buf
;
62 atomic_inc(&buf
->refcount
);
67 static void vb2_dma_contig_put(void *buf_priv
)
69 struct vb2_dc_buf
*buf
= buf_priv
;
71 if (atomic_dec_and_test(&buf
->refcount
)) {
72 dma_free_coherent(buf
->conf
->dev
, buf
->size
, buf
->vaddr
,
78 static void *vb2_dma_contig_cookie(void *buf_priv
)
80 struct vb2_dc_buf
*buf
= buf_priv
;
82 return &buf
->dma_addr
;
85 static void *vb2_dma_contig_vaddr(void *buf_priv
)
87 struct vb2_dc_buf
*buf
= buf_priv
;
94 static unsigned int vb2_dma_contig_num_users(void *buf_priv
)
96 struct vb2_dc_buf
*buf
= buf_priv
;
98 return atomic_read(&buf
->refcount
);
101 static int vb2_dma_contig_mmap(void *buf_priv
, struct vm_area_struct
*vma
)
103 struct vb2_dc_buf
*buf
= buf_priv
;
106 printk(KERN_ERR
"No buffer to map\n");
110 return vb2_mmap_pfn_range(vma
, buf
->dma_addr
, buf
->size
,
111 &vb2_common_vm_ops
, &buf
->handler
);
114 static void *vb2_dma_contig_get_userptr(void *alloc_ctx
, unsigned long vaddr
,
115 unsigned long size
, int write
)
117 struct vb2_dc_buf
*buf
;
118 struct vm_area_struct
*vma
;
119 dma_addr_t dma_addr
= 0;
122 buf
= kzalloc(sizeof *buf
, GFP_KERNEL
);
124 return ERR_PTR(-ENOMEM
);
126 ret
= vb2_get_contig_userptr(vaddr
, size
, &vma
, &dma_addr
);
128 printk(KERN_ERR
"Failed acquiring VMA for vaddr 0x%08lx\n",
135 buf
->dma_addr
= dma_addr
;
141 static void vb2_dma_contig_put_userptr(void *mem_priv
)
143 struct vb2_dc_buf
*buf
= mem_priv
;
148 vb2_put_vma(buf
->vma
);
152 const struct vb2_mem_ops vb2_dma_contig_memops
= {
153 .alloc
= vb2_dma_contig_alloc
,
154 .put
= vb2_dma_contig_put
,
155 .cookie
= vb2_dma_contig_cookie
,
156 .vaddr
= vb2_dma_contig_vaddr
,
157 .mmap
= vb2_dma_contig_mmap
,
158 .get_userptr
= vb2_dma_contig_get_userptr
,
159 .put_userptr
= vb2_dma_contig_put_userptr
,
160 .num_users
= vb2_dma_contig_num_users
,
162 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops
);
164 void *vb2_dma_contig_init_ctx(struct device
*dev
)
166 struct vb2_dc_conf
*conf
;
168 conf
= kzalloc(sizeof *conf
, GFP_KERNEL
);
170 return ERR_PTR(-ENOMEM
);
176 EXPORT_SYMBOL_GPL(vb2_dma_contig_init_ctx
);
178 void vb2_dma_contig_cleanup_ctx(void *alloc_ctx
)
182 EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx
);
184 MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2");
185 MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
186 MODULE_LICENSE("GPL");