2 * videobuf2-vmalloc.c - vmalloc 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>
15 #include <linux/slab.h>
16 #include <linux/vmalloc.h>
18 #include <media/videobuf2-core.h>
19 #include <media/videobuf2-memops.h>
21 struct vb2_vmalloc_buf
{
25 struct vb2_vmarea_handler handler
;
28 static void vb2_vmalloc_put(void *buf_priv
);
30 static void *vb2_vmalloc_alloc(void *alloc_ctx
, unsigned long size
)
32 struct vb2_vmalloc_buf
*buf
;
34 buf
= kzalloc(sizeof *buf
, GFP_KERNEL
);
39 buf
->vaddr
= vmalloc_user(buf
->size
);
40 buf
->handler
.refcount
= &buf
->refcount
;
41 buf
->handler
.put
= vb2_vmalloc_put
;
42 buf
->handler
.arg
= buf
;
45 printk(KERN_ERR
"vmalloc of size %ld failed\n", buf
->size
);
50 atomic_inc(&buf
->refcount
);
51 printk(KERN_DEBUG
"Allocated vmalloc buffer of size %ld at vaddr=%p\n",
52 buf
->size
, buf
->vaddr
);
57 static void vb2_vmalloc_put(void *buf_priv
)
59 struct vb2_vmalloc_buf
*buf
= buf_priv
;
61 if (atomic_dec_and_test(&buf
->refcount
)) {
62 printk(KERN_DEBUG
"%s: Freeing vmalloc mem at vaddr=%p\n",
63 __func__
, buf
->vaddr
);
69 static void *vb2_vmalloc_vaddr(void *buf_priv
)
71 struct vb2_vmalloc_buf
*buf
= buf_priv
;
76 printk(KERN_ERR
"Address of an unallocated plane requested\n");
83 static unsigned int vb2_vmalloc_num_users(void *buf_priv
)
85 struct vb2_vmalloc_buf
*buf
= buf_priv
;
86 return atomic_read(&buf
->refcount
);
89 static int vb2_vmalloc_mmap(void *buf_priv
, struct vm_area_struct
*vma
)
91 struct vb2_vmalloc_buf
*buf
= buf_priv
;
95 printk(KERN_ERR
"No memory to map\n");
99 ret
= remap_vmalloc_range(vma
, buf
->vaddr
, 0);
101 printk(KERN_ERR
"Remapping vmalloc memory, error: %d\n", ret
);
106 * Make sure that vm_areas for 2 buffers won't be merged together
108 vma
->vm_flags
|= VM_DONTEXPAND
;
111 * Use common vm_area operations to track buffer refcount.
113 vma
->vm_private_data
= &buf
->handler
;
114 vma
->vm_ops
= &vb2_common_vm_ops
;
116 vma
->vm_ops
->open(vma
);
121 const struct vb2_mem_ops vb2_vmalloc_memops
= {
122 .alloc
= vb2_vmalloc_alloc
,
123 .put
= vb2_vmalloc_put
,
124 .vaddr
= vb2_vmalloc_vaddr
,
125 .mmap
= vb2_vmalloc_mmap
,
126 .num_users
= vb2_vmalloc_num_users
,
128 EXPORT_SYMBOL_GPL(vb2_vmalloc_memops
);
130 MODULE_DESCRIPTION("vmalloc memory handling routines for videobuf2");
131 MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
132 MODULE_LICENSE("GPL");