WIP FPC-III support
[linux/fpc-iii.git] / drivers / media / v4l2-core / videobuf-dma-contig.c
blob52312ce2ba0562b24fe4a90307a3d9110c34f6e8
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * helper functions for physically contiguous capture buffers
5 * The functions support hardware lacking scatter gather support
6 * (i.e. the buffers must be linear in physical memory)
8 * Copyright (c) 2008 Magnus Damm
10 * Based on videobuf-vmalloc.c,
11 * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org>
14 #include <linux/init.h>
15 #include <linux/module.h>
16 #include <linux/mm.h>
17 #include <linux/pagemap.h>
18 #include <linux/dma-mapping.h>
19 #include <linux/sched.h>
20 #include <linux/slab.h>
21 #include <media/videobuf-dma-contig.h>
23 struct videobuf_dma_contig_memory {
24 u32 magic;
25 void *vaddr;
26 dma_addr_t dma_handle;
27 unsigned long size;
30 #define MAGIC_DC_MEM 0x0733ac61
31 #define MAGIC_CHECK(is, should) \
32 if (unlikely((is) != (should))) { \
33 pr_err("magic mismatch: %x expected %x\n", (is), (should)); \
34 BUG(); \
37 static int __videobuf_dc_alloc(struct device *dev,
38 struct videobuf_dma_contig_memory *mem,
39 unsigned long size, gfp_t flags)
41 mem->size = size;
42 mem->vaddr = dma_alloc_coherent(dev, mem->size,
43 &mem->dma_handle, flags);
45 if (!mem->vaddr) {
46 dev_err(dev, "memory alloc size %ld failed\n", mem->size);
47 return -ENOMEM;
50 dev_dbg(dev, "dma mapped data is at %p (%ld)\n", mem->vaddr, mem->size);
52 return 0;
55 static void __videobuf_dc_free(struct device *dev,
56 struct videobuf_dma_contig_memory *mem)
58 dma_free_coherent(dev, mem->size, mem->vaddr, mem->dma_handle);
60 mem->vaddr = NULL;
63 static void videobuf_vm_open(struct vm_area_struct *vma)
65 struct videobuf_mapping *map = vma->vm_private_data;
67 dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
68 map, map->count, vma->vm_start, vma->vm_end);
70 map->count++;
73 static void videobuf_vm_close(struct vm_area_struct *vma)
75 struct videobuf_mapping *map = vma->vm_private_data;
76 struct videobuf_queue *q = map->q;
77 int i;
79 dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
80 map, map->count, vma->vm_start, vma->vm_end);
82 map->count--;
83 if (0 == map->count) {
84 struct videobuf_dma_contig_memory *mem;
86 dev_dbg(q->dev, "munmap %p q=%p\n", map, q);
87 videobuf_queue_lock(q);
89 /* We need first to cancel streams, before unmapping */
90 if (q->streaming)
91 videobuf_queue_cancel(q);
93 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
94 if (NULL == q->bufs[i])
95 continue;
97 if (q->bufs[i]->map != map)
98 continue;
100 mem = q->bufs[i]->priv;
101 if (mem) {
102 /* This callback is called only if kernel has
103 allocated memory and this memory is mmapped.
104 In this case, memory should be freed,
105 in order to do memory unmap.
108 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
110 /* vfree is not atomic - can't be
111 called with IRQ's disabled
113 dev_dbg(q->dev, "buf[%d] freeing %p\n",
114 i, mem->vaddr);
116 __videobuf_dc_free(q->dev, mem);
117 mem->vaddr = NULL;
120 q->bufs[i]->map = NULL;
121 q->bufs[i]->baddr = 0;
124 kfree(map);
126 videobuf_queue_unlock(q);
130 static const struct vm_operations_struct videobuf_vm_ops = {
131 .open = videobuf_vm_open,
132 .close = videobuf_vm_close,
136 * videobuf_dma_contig_user_put() - reset pointer to user space buffer
137 * @mem: per-buffer private videobuf-dma-contig data
139 * This function resets the user space pointer
141 static void videobuf_dma_contig_user_put(struct videobuf_dma_contig_memory *mem)
143 mem->dma_handle = 0;
144 mem->size = 0;
148 * videobuf_dma_contig_user_get() - setup user space memory pointer
149 * @mem: per-buffer private videobuf-dma-contig data
150 * @vb: video buffer to map
152 * This function validates and sets up a pointer to user space memory.
153 * Only physically contiguous pfn-mapped memory is accepted.
155 * Returns 0 if successful.
157 static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
158 struct videobuf_buffer *vb)
160 unsigned long untagged_baddr = untagged_addr(vb->baddr);
161 struct mm_struct *mm = current->mm;
162 struct vm_area_struct *vma;
163 unsigned long prev_pfn, this_pfn;
164 unsigned long pages_done, user_address;
165 unsigned int offset;
166 int ret;
168 offset = untagged_baddr & ~PAGE_MASK;
169 mem->size = PAGE_ALIGN(vb->size + offset);
170 ret = -EINVAL;
172 mmap_read_lock(mm);
174 vma = find_vma(mm, untagged_baddr);
175 if (!vma)
176 goto out_up;
178 if ((untagged_baddr + mem->size) > vma->vm_end)
179 goto out_up;
181 pages_done = 0;
182 prev_pfn = 0; /* kill warning */
183 user_address = untagged_baddr;
185 while (pages_done < (mem->size >> PAGE_SHIFT)) {
186 ret = follow_pfn(vma, user_address, &this_pfn);
187 if (ret)
188 break;
190 if (pages_done == 0)
191 mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset;
192 else if (this_pfn != (prev_pfn + 1))
193 ret = -EFAULT;
195 if (ret)
196 break;
198 prev_pfn = this_pfn;
199 user_address += PAGE_SIZE;
200 pages_done++;
203 out_up:
204 mmap_read_unlock(current->mm);
206 return ret;
209 static struct videobuf_buffer *__videobuf_alloc(size_t size)
211 struct videobuf_dma_contig_memory *mem;
212 struct videobuf_buffer *vb;
214 vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
215 if (vb) {
216 vb->priv = ((char *)vb) + size;
217 mem = vb->priv;
218 mem->magic = MAGIC_DC_MEM;
221 return vb;
224 static void *__videobuf_to_vaddr(struct videobuf_buffer *buf)
226 struct videobuf_dma_contig_memory *mem = buf->priv;
228 BUG_ON(!mem);
229 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
231 return mem->vaddr;
234 static int __videobuf_iolock(struct videobuf_queue *q,
235 struct videobuf_buffer *vb,
236 struct v4l2_framebuffer *fbuf)
238 struct videobuf_dma_contig_memory *mem = vb->priv;
240 BUG_ON(!mem);
241 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
243 switch (vb->memory) {
244 case V4L2_MEMORY_MMAP:
245 dev_dbg(q->dev, "%s memory method MMAP\n", __func__);
247 /* All handling should be done by __videobuf_mmap_mapper() */
248 if (!mem->vaddr) {
249 dev_err(q->dev, "memory is not allocated/mmapped.\n");
250 return -EINVAL;
252 break;
253 case V4L2_MEMORY_USERPTR:
254 dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
256 /* handle pointer from user space */
257 if (vb->baddr)
258 return videobuf_dma_contig_user_get(mem, vb);
260 /* allocate memory for the read() method */
261 if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size),
262 GFP_KERNEL))
263 return -ENOMEM;
264 break;
265 case V4L2_MEMORY_OVERLAY:
266 default:
267 dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n", __func__);
268 return -EINVAL;
271 return 0;
274 static int __videobuf_mmap_mapper(struct videobuf_queue *q,
275 struct videobuf_buffer *buf,
276 struct vm_area_struct *vma)
278 struct videobuf_dma_contig_memory *mem;
279 struct videobuf_mapping *map;
280 int retval;
282 dev_dbg(q->dev, "%s\n", __func__);
284 /* create mapping + update buffer list */
285 map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
286 if (!map)
287 return -ENOMEM;
289 buf->map = map;
290 map->q = q;
292 buf->baddr = vma->vm_start;
294 mem = buf->priv;
295 BUG_ON(!mem);
296 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
298 if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize),
299 GFP_KERNEL | __GFP_COMP))
300 goto error;
302 /* Try to remap memory */
303 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
305 /* the "vm_pgoff" is just used in v4l2 to find the
306 * corresponding buffer data structure which is allocated
307 * earlier and it does not mean the offset from the physical
308 * buffer start address as usual. So set it to 0 to pass
309 * the sanity check in vm_iomap_memory().
311 vma->vm_pgoff = 0;
313 retval = vm_iomap_memory(vma, mem->dma_handle, mem->size);
314 if (retval) {
315 dev_err(q->dev, "mmap: remap failed with error %d. ",
316 retval);
317 dma_free_coherent(q->dev, mem->size,
318 mem->vaddr, mem->dma_handle);
319 goto error;
322 vma->vm_ops = &videobuf_vm_ops;
323 vma->vm_flags |= VM_DONTEXPAND;
324 vma->vm_private_data = map;
326 dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
327 map, q, vma->vm_start, vma->vm_end,
328 (long int)buf->bsize, vma->vm_pgoff, buf->i);
330 videobuf_vm_open(vma);
332 return 0;
334 error:
335 kfree(map);
336 return -ENOMEM;
339 static struct videobuf_qtype_ops qops = {
340 .magic = MAGIC_QTYPE_OPS,
341 .alloc_vb = __videobuf_alloc,
342 .iolock = __videobuf_iolock,
343 .mmap_mapper = __videobuf_mmap_mapper,
344 .vaddr = __videobuf_to_vaddr,
347 void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
348 const struct videobuf_queue_ops *ops,
349 struct device *dev,
350 spinlock_t *irqlock,
351 enum v4l2_buf_type type,
352 enum v4l2_field field,
353 unsigned int msize,
354 void *priv,
355 struct mutex *ext_lock)
357 videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
358 priv, &qops, ext_lock);
360 EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init);
362 dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf)
364 struct videobuf_dma_contig_memory *mem = buf->priv;
366 BUG_ON(!mem);
367 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
369 return mem->dma_handle;
371 EXPORT_SYMBOL_GPL(videobuf_to_dma_contig);
373 void videobuf_dma_contig_free(struct videobuf_queue *q,
374 struct videobuf_buffer *buf)
376 struct videobuf_dma_contig_memory *mem = buf->priv;
378 /* mmapped memory can't be freed here, otherwise mmapped region
379 would be released, while still needed. In this case, the memory
380 release should happen inside videobuf_vm_close().
381 So, it should free memory only if the memory were allocated for
382 read() operation.
384 if (buf->memory != V4L2_MEMORY_USERPTR)
385 return;
387 if (!mem)
388 return;
390 MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
392 /* handle user space pointer case */
393 if (buf->baddr) {
394 videobuf_dma_contig_user_put(mem);
395 return;
398 /* read() method */
399 if (mem->vaddr) {
400 __videobuf_dc_free(q->dev, mem);
401 mem->vaddr = NULL;
404 EXPORT_SYMBOL_GPL(videobuf_dma_contig_free);
406 MODULE_DESCRIPTION("helper module to manage video4linux dma contig buffers");
407 MODULE_AUTHOR("Magnus Damm");
408 MODULE_LICENSE("GPL");