diff options
author | Jan Kara <jack@suse.cz> | 2015-07-13 10:55:46 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-08-16 12:10:42 -0400 |
commit | 21fb0cb7ec65a40b9f5f7cda59eba0eb2ae76473 (patch) | |
tree | e0cccb86717f351e3bc6c38811cb093c65837f07 | |
parent | 8a677b6eddfc3127ea36a710838ecd20502b1cb9 (diff) |
[media] vb2: Provide helpers for mapping virtual addresses
Provide simple helper functions to map virtual address range into an
array of pfns / pages.
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r-- | drivers/media/v4l2-core/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/v4l2-core/videobuf2-memops.c | 58 | ||||
-rw-r--r-- | include/media/videobuf2-memops.h | 5 |
3 files changed, 64 insertions, 0 deletions
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index b4b022933e29..82876a67f144 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig | |||
@@ -84,6 +84,7 @@ config VIDEOBUF2_CORE | |||
84 | 84 | ||
85 | config VIDEOBUF2_MEMOPS | 85 | config VIDEOBUF2_MEMOPS |
86 | tristate | 86 | tristate |
87 | select FRAME_VECTOR | ||
87 | 88 | ||
88 | config VIDEOBUF2_DMA_CONTIG | 89 | config VIDEOBUF2_DMA_CONTIG |
89 | tristate | 90 | tristate |
diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c index 81c1ad8b2cf1..0ec186d41b9b 100644 --- a/drivers/media/v4l2-core/videobuf2-memops.c +++ b/drivers/media/v4l2-core/videobuf2-memops.c | |||
@@ -137,6 +137,64 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size, | |||
137 | EXPORT_SYMBOL_GPL(vb2_get_contig_userptr); | 137 | EXPORT_SYMBOL_GPL(vb2_get_contig_userptr); |
138 | 138 | ||
139 | /** | 139 | /** |
140 | * vb2_create_framevec() - map virtual addresses to pfns | ||
141 | * @start: Virtual user address where we start mapping | ||
142 | * @length: Length of a range to map | ||
143 | * @write: Should we map for writing into the area | ||
144 | * | ||
145 | * This function allocates and fills in a vector with pfns corresponding to | ||
146 | * virtual address range passed in arguments. If pfns have corresponding pages, | ||
147 | * page references are also grabbed to pin pages in memory. The function | ||
148 | * returns pointer to the vector on success and error pointer in case of | ||
149 | * failure. Returned vector needs to be freed via vb2_destroy_pfnvec(). | ||
150 | */ | ||
151 | struct frame_vector *vb2_create_framevec(unsigned long start, | ||
152 | unsigned long length, | ||
153 | bool write) | ||
154 | { | ||
155 | int ret; | ||
156 | unsigned long first, last; | ||
157 | unsigned long nr; | ||
158 | struct frame_vector *vec; | ||
159 | |||
160 | first = start >> PAGE_SHIFT; | ||
161 | last = (start + length - 1) >> PAGE_SHIFT; | ||
162 | nr = last - first + 1; | ||
163 | vec = frame_vector_create(nr); | ||
164 | if (!vec) | ||
165 | return ERR_PTR(-ENOMEM); | ||
166 | ret = get_vaddr_frames(start, nr, write, 1, vec); | ||
167 | if (ret < 0) | ||
168 | goto out_destroy; | ||
169 | /* We accept only complete set of PFNs */ | ||
170 | if (ret != nr) { | ||
171 | ret = -EFAULT; | ||
172 | goto out_release; | ||
173 | } | ||
174 | return vec; | ||
175 | out_release: | ||
176 | put_vaddr_frames(vec); | ||
177 | out_destroy: | ||
178 | frame_vector_destroy(vec); | ||
179 | return ERR_PTR(ret); | ||
180 | } | ||
181 | EXPORT_SYMBOL(vb2_create_framevec); | ||
182 | |||
183 | /** | ||
184 | * vb2_destroy_framevec() - release vector of mapped pfns | ||
185 | * @vec: vector of pfns / pages to release | ||
186 | * | ||
187 | * This releases references to all pages in the vector @vec (if corresponding | ||
188 | * pfns are backed by pages) and frees the passed vector. | ||
189 | */ | ||
190 | void vb2_destroy_framevec(struct frame_vector *vec) | ||
191 | { | ||
192 | put_vaddr_frames(vec); | ||
193 | frame_vector_destroy(vec); | ||
194 | } | ||
195 | EXPORT_SYMBOL(vb2_destroy_framevec); | ||
196 | |||
197 | /** | ||
140 | * vb2_common_vm_open() - increase refcount of the vma | 198 | * vb2_common_vm_open() - increase refcount of the vma |
141 | * @vma: virtual memory region for the mapping | 199 | * @vma: virtual memory region for the mapping |
142 | * | 200 | * |
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h index f05444ca8c0c..2f0564ff5f31 100644 --- a/include/media/videobuf2-memops.h +++ b/include/media/videobuf2-memops.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #define _MEDIA_VIDEOBUF2_MEMOPS_H | 15 | #define _MEDIA_VIDEOBUF2_MEMOPS_H |
16 | 16 | ||
17 | #include <media/videobuf2-core.h> | 17 | #include <media/videobuf2-core.h> |
18 | #include <linux/mm.h> | ||
18 | 19 | ||
19 | /** | 20 | /** |
20 | * vb2_vmarea_handler - common vma refcount tracking handler | 21 | * vb2_vmarea_handler - common vma refcount tracking handler |
@@ -36,5 +37,9 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size, | |||
36 | struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma); | 37 | struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma); |
37 | void vb2_put_vma(struct vm_area_struct *vma); | 38 | void vb2_put_vma(struct vm_area_struct *vma); |
38 | 39 | ||
40 | struct frame_vector *vb2_create_framevec(unsigned long start, | ||
41 | unsigned long length, | ||
42 | bool write); | ||
43 | void vb2_destroy_framevec(struct frame_vector *vec); | ||
39 | 44 | ||
40 | #endif | 45 | #endif |