diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 5 | ||||
-rw-r--r-- | arch/Kconfig | 3 | ||||
-rw-r--r-- | drivers/base/Kconfig | 89 | ||||
-rw-r--r-- | drivers/base/Makefile | 1 | ||||
-rw-r--r-- | drivers/base/dma-contiguous.c | 401 | ||||
-rw-r--r-- | include/asm-generic/dma-contiguous.h | 28 | ||||
-rw-r--r-- | include/linux/device.h | 4 | ||||
-rw-r--r-- | include/linux/dma-contiguous.h | 110 |
8 files changed, 641 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index c1601e5a8b71..669e8bb52b94 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -508,6 +508,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
508 | Also note the kernel might malfunction if you disable | 508 | Also note the kernel might malfunction if you disable |
509 | some critical bits. | 509 | some critical bits. |
510 | 510 | ||
511 | cma=nn[MG] [ARM,KNL] | ||
512 | Sets the size of kernel global memory area for contiguous | ||
513 | memory allocations. For more information, see | ||
514 | include/linux/dma-contiguous.h | ||
515 | |||
511 | cmo_free_hint= [PPC] Format: { yes | no } | 516 | cmo_free_hint= [PPC] Format: { yes | no } |
512 | Specify whether pages are marked as being inactive | 517 | Specify whether pages are marked as being inactive |
513 | when they are freed. This is used in CMO environments | 518 | when they are freed. This is used in CMO environments |
diff --git a/arch/Kconfig b/arch/Kconfig index 684eb5af439d..0a3ffe46e567 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -142,6 +142,9 @@ config HAVE_ARCH_TRACEHOOK | |||
142 | config HAVE_DMA_ATTRS | 142 | config HAVE_DMA_ATTRS |
143 | bool | 143 | bool |
144 | 144 | ||
145 | config HAVE_DMA_CONTIGUOUS | ||
146 | bool | ||
147 | |||
145 | config USE_GENERIC_SMP_HELPERS | 148 | config USE_GENERIC_SMP_HELPERS |
146 | bool | 149 | bool |
147 | 150 | ||
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 9aa618acfe97..9b21469482ae 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
@@ -192,4 +192,93 @@ config DMA_SHARED_BUFFER | |||
192 | APIs extension; the file's descriptor can then be passed on to other | 192 | APIs extension; the file's descriptor can then be passed on to other |
193 | driver. | 193 | driver. |
194 | 194 | ||
195 | config CMA | ||
196 | bool "Contiguous Memory Allocator (EXPERIMENTAL)" | ||
197 | depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK && EXPERIMENTAL | ||
198 | select MIGRATION | ||
199 | help | ||
200 | This enables the Contiguous Memory Allocator which allows drivers | ||
201 | to allocate big physically-contiguous blocks of memory for use with | ||
202 | hardware components that do not support I/O map nor scatter-gather. | ||
203 | |||
204 | For more information see <include/linux/dma-contiguous.h>. | ||
205 | If unsure, say "n". | ||
206 | |||
207 | if CMA | ||
208 | |||
209 | config CMA_DEBUG | ||
210 | bool "CMA debug messages (DEVELOPMENT)" | ||
211 | depends on DEBUG_KERNEL | ||
212 | help | ||
213 | Turns on debug messages in CMA. This produces KERN_DEBUG | ||
214 | messages for every CMA call as well as various messages while | ||
215 | processing calls such as dma_alloc_from_contiguous(). | ||
216 | This option does not affect warning and error messages. | ||
217 | |||
218 | comment "Default contiguous memory area size:" | ||
219 | |||
220 | config CMA_SIZE_MBYTES | ||
221 | int "Size in Mega Bytes" | ||
222 | depends on !CMA_SIZE_SEL_PERCENTAGE | ||
223 | default 16 | ||
224 | help | ||
225 | Defines the size (in MiB) of the default memory area for Contiguous | ||
226 | Memory Allocator. | ||
227 | |||
228 | config CMA_SIZE_PERCENTAGE | ||
229 | int "Percentage of total memory" | ||
230 | depends on !CMA_SIZE_SEL_MBYTES | ||
231 | default 10 | ||
232 | help | ||
233 | Defines the size of the default memory area for Contiguous Memory | ||
234 | Allocator as a percentage of the total memory in the system. | ||
235 | |||
236 | choice | ||
237 | prompt "Selected region size" | ||
238 | default CMA_SIZE_SEL_ABSOLUTE | ||
239 | |||
240 | config CMA_SIZE_SEL_MBYTES | ||
241 | bool "Use mega bytes value only" | ||
242 | |||
243 | config CMA_SIZE_SEL_PERCENTAGE | ||
244 | bool "Use percentage value only" | ||
245 | |||
246 | config CMA_SIZE_SEL_MIN | ||
247 | bool "Use lower value (minimum)" | ||
248 | |||
249 | config CMA_SIZE_SEL_MAX | ||
250 | bool "Use higher value (maximum)" | ||
251 | |||
252 | endchoice | ||
253 | |||
254 | config CMA_ALIGNMENT | ||
255 | int "Maximum PAGE_SIZE order of alignment for contiguous buffers" | ||
256 | range 4 9 | ||
257 | default 8 | ||
258 | help | ||
259 | DMA mapping framework by default aligns all buffers to the smallest | ||
260 | PAGE_SIZE order which is greater than or equal to the requested buffer | ||
261 | size. This works well for buffers up to a few hundreds kilobytes, but | ||
262 | for larger buffers it just a memory waste. With this parameter you can | ||
263 | specify the maximum PAGE_SIZE order for contiguous buffers. Larger | ||
264 | buffers will be aligned only to this specified order. The order is | ||
265 | expressed as a power of two multiplied by the PAGE_SIZE. | ||
266 | |||
267 | For example, if your system defaults to 4KiB pages, the order value | ||
268 | of 8 means that the buffers will be aligned up to 1MiB only. | ||
269 | |||
270 | If unsure, leave the default value "8". | ||
271 | |||
272 | config CMA_AREAS | ||
273 | int "Maximum count of the CMA device-private areas" | ||
274 | default 7 | ||
275 | help | ||
276 | CMA allows to create CMA areas for particular devices. This parameter | ||
277 | sets the maximum number of such device private CMA areas in the | ||
278 | system. | ||
279 | |||
280 | If unsure, leave the default value "7". | ||
281 | |||
282 | endif | ||
283 | |||
195 | endmenu | 284 | endmenu |
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index b6d1b9c4200c..5aa2d703d19f 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -6,6 +6,7 @@ obj-y := core.o bus.o dd.o syscore.o \ | |||
6 | attribute_container.o transport_class.o \ | 6 | attribute_container.o transport_class.o \ |
7 | topology.o | 7 | topology.o |
8 | obj-$(CONFIG_DEVTMPFS) += devtmpfs.o | 8 | obj-$(CONFIG_DEVTMPFS) += devtmpfs.o |
9 | obj-$(CONFIG_CMA) += dma-contiguous.o | ||
9 | obj-y += power/ | 10 | obj-y += power/ |
10 | obj-$(CONFIG_HAS_DMA) += dma-mapping.o | 11 | obj-$(CONFIG_HAS_DMA) += dma-mapping.o |
11 | obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o | 12 | obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o |
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c new file mode 100644 index 000000000000..78efb0306a44 --- /dev/null +++ b/drivers/base/dma-contiguous.c | |||
@@ -0,0 +1,401 @@ | |||
1 | /* | ||
2 | * Contiguous Memory Allocator for DMA mapping framework | ||
3 | * Copyright (c) 2010-2011 by Samsung Electronics. | ||
4 | * Written by: | ||
5 | * Marek Szyprowski <m.szyprowski@samsung.com> | ||
6 | * Michal Nazarewicz <mina86@mina86.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of the | ||
11 | * License or (at your optional) any later version of the license. | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) "cma: " fmt | ||
15 | |||
16 | #ifdef CONFIG_CMA_DEBUG | ||
17 | #ifndef DEBUG | ||
18 | # define DEBUG | ||
19 | #endif | ||
20 | #endif | ||
21 | |||
22 | #include <asm/page.h> | ||
23 | #include <asm/dma-contiguous.h> | ||
24 | |||
25 | #include <linux/memblock.h> | ||
26 | #include <linux/err.h> | ||
27 | #include <linux/mm.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <linux/page-isolation.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/swap.h> | ||
32 | #include <linux/mm_types.h> | ||
33 | #include <linux/dma-contiguous.h> | ||
34 | |||
35 | #ifndef SZ_1M | ||
36 | #define SZ_1M (1 << 20) | ||
37 | #endif | ||
38 | |||
39 | struct cma { | ||
40 | unsigned long base_pfn; | ||
41 | unsigned long count; | ||
42 | unsigned long *bitmap; | ||
43 | }; | ||
44 | |||
45 | struct cma *dma_contiguous_default_area; | ||
46 | |||
47 | #ifdef CONFIG_CMA_SIZE_MBYTES | ||
48 | #define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES | ||
49 | #else | ||
50 | #define CMA_SIZE_MBYTES 0 | ||
51 | #endif | ||
52 | |||
53 | /* | ||
54 | * Default global CMA area size can be defined in kernel's .config. | ||
55 | * This is usefull mainly for distro maintainers to create a kernel | ||
56 | * that works correctly for most supported systems. | ||
57 | * The size can be set in bytes or as a percentage of the total memory | ||
58 | * in the system. | ||
59 | * | ||
60 | * Users, who want to set the size of global CMA area for their system | ||
61 | * should use cma= kernel parameter. | ||
62 | */ | ||
63 | static const unsigned long size_bytes = CMA_SIZE_MBYTES * SZ_1M; | ||
64 | static long size_cmdline = -1; | ||
65 | |||
66 | static int __init early_cma(char *p) | ||
67 | { | ||
68 | pr_debug("%s(%s)\n", __func__, p); | ||
69 | size_cmdline = memparse(p, &p); | ||
70 | return 0; | ||
71 | } | ||
72 | early_param("cma", early_cma); | ||
73 | |||
74 | #ifdef CONFIG_CMA_SIZE_PERCENTAGE | ||
75 | |||
76 | static unsigned long __init __maybe_unused cma_early_percent_memory(void) | ||
77 | { | ||
78 | struct memblock_region *reg; | ||
79 | unsigned long total_pages = 0; | ||
80 | |||
81 | /* | ||
82 | * We cannot use memblock_phys_mem_size() here, because | ||
83 | * memblock_analyze() has not been called yet. | ||
84 | */ | ||
85 | for_each_memblock(memory, reg) | ||
86 | total_pages += memblock_region_memory_end_pfn(reg) - | ||
87 | memblock_region_memory_base_pfn(reg); | ||
88 | |||
89 | return (total_pages * CONFIG_CMA_SIZE_PERCENTAGE / 100) << PAGE_SHIFT; | ||
90 | } | ||
91 | |||
92 | #else | ||
93 | |||
94 | static inline __maybe_unused unsigned long cma_early_percent_memory(void) | ||
95 | { | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | #endif | ||
100 | |||
101 | /** | ||
102 | * dma_contiguous_reserve() - reserve area for contiguous memory handling | ||
103 | * @limit: End address of the reserved memory (optional, 0 for any). | ||
104 | * | ||
105 | * This function reserves memory from early allocator. It should be | ||
106 | * called by arch specific code once the early allocator (memblock or bootmem) | ||
107 | * has been activated and all other subsystems have already allocated/reserved | ||
108 | * memory. | ||
109 | */ | ||
110 | void __init dma_contiguous_reserve(phys_addr_t limit) | ||
111 | { | ||
112 | unsigned long selected_size = 0; | ||
113 | |||
114 | pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit); | ||
115 | |||
116 | if (size_cmdline != -1) { | ||
117 | selected_size = size_cmdline; | ||
118 | } else { | ||
119 | #ifdef CONFIG_CMA_SIZE_SEL_MBYTES | ||
120 | selected_size = size_bytes; | ||
121 | #elif defined(CONFIG_CMA_SIZE_SEL_PERCENTAGE) | ||
122 | selected_size = cma_early_percent_memory(); | ||
123 | #elif defined(CONFIG_CMA_SIZE_SEL_MIN) | ||
124 | selected_size = min(size_bytes, cma_early_percent_memory()); | ||
125 | #elif defined(CONFIG_CMA_SIZE_SEL_MAX) | ||
126 | selected_size = max(size_bytes, cma_early_percent_memory()); | ||
127 | #endif | ||
128 | } | ||
129 | |||
130 | if (selected_size) { | ||
131 | pr_debug("%s: reserving %ld MiB for global area\n", __func__, | ||
132 | selected_size / SZ_1M); | ||
133 | |||
134 | dma_declare_contiguous(NULL, selected_size, 0, limit); | ||
135 | } | ||
136 | }; | ||
137 | |||
138 | static DEFINE_MUTEX(cma_mutex); | ||
139 | |||
140 | static __init int cma_activate_area(unsigned long base_pfn, unsigned long count) | ||
141 | { | ||
142 | unsigned long pfn = base_pfn; | ||
143 | unsigned i = count >> pageblock_order; | ||
144 | struct zone *zone; | ||
145 | |||
146 | WARN_ON_ONCE(!pfn_valid(pfn)); | ||
147 | zone = page_zone(pfn_to_page(pfn)); | ||
148 | |||
149 | do { | ||
150 | unsigned j; | ||
151 | base_pfn = pfn; | ||
152 | for (j = pageblock_nr_pages; j; --j, pfn++) { | ||
153 | WARN_ON_ONCE(!pfn_valid(pfn)); | ||
154 | if (page_zone(pfn_to_page(pfn)) != zone) | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | init_cma_reserved_pageblock(pfn_to_page(base_pfn)); | ||
158 | } while (--i); | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static __init struct cma *cma_create_area(unsigned long base_pfn, | ||
163 | unsigned long count) | ||
164 | { | ||
165 | int bitmap_size = BITS_TO_LONGS(count) * sizeof(long); | ||
166 | struct cma *cma; | ||
167 | int ret = -ENOMEM; | ||
168 | |||
169 | pr_debug("%s(base %08lx, count %lx)\n", __func__, base_pfn, count); | ||
170 | |||
171 | cma = kmalloc(sizeof *cma, GFP_KERNEL); | ||
172 | if (!cma) | ||
173 | return ERR_PTR(-ENOMEM); | ||
174 | |||
175 | cma->base_pfn = base_pfn; | ||
176 | cma->count = count; | ||
177 | cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL); | ||
178 | |||
179 | if (!cma->bitmap) | ||
180 | goto no_mem; | ||
181 | |||
182 | ret = cma_activate_area(base_pfn, count); | ||
183 | if (ret) | ||
184 | goto error; | ||
185 | |||
186 | pr_debug("%s: returned %p\n", __func__, (void *)cma); | ||
187 | return cma; | ||
188 | |||
189 | error: | ||
190 | kfree(cma->bitmap); | ||
191 | no_mem: | ||
192 | kfree(cma); | ||
193 | return ERR_PTR(ret); | ||
194 | } | ||
195 | |||
196 | static struct cma_reserved { | ||
197 | phys_addr_t start; | ||
198 | unsigned long size; | ||
199 | struct device *dev; | ||
200 | } cma_reserved[MAX_CMA_AREAS] __initdata; | ||
201 | static unsigned cma_reserved_count __initdata; | ||
202 | |||
203 | static int __init cma_init_reserved_areas(void) | ||
204 | { | ||
205 | struct cma_reserved *r = cma_reserved; | ||
206 | unsigned i = cma_reserved_count; | ||
207 | |||
208 | pr_debug("%s()\n", __func__); | ||
209 | |||
210 | for (; i; --i, ++r) { | ||
211 | struct cma *cma; | ||
212 | cma = cma_create_area(PFN_DOWN(r->start), | ||
213 | r->size >> PAGE_SHIFT); | ||
214 | if (!IS_ERR(cma)) | ||
215 | dev_set_cma_area(r->dev, cma); | ||
216 | } | ||
217 | return 0; | ||
218 | } | ||
219 | core_initcall(cma_init_reserved_areas); | ||
220 | |||
221 | /** | ||
222 | * dma_declare_contiguous() - reserve area for contiguous memory handling | ||
223 | * for particular device | ||
224 | * @dev: Pointer to device structure. | ||
225 | * @size: Size of the reserved memory. | ||
226 | * @base: Start address of the reserved memory (optional, 0 for any). | ||
227 | * @limit: End address of the reserved memory (optional, 0 for any). | ||
228 | * | ||
229 | * This function reserves memory for specified device. It should be | ||
230 | * called by board specific code when early allocator (memblock or bootmem) | ||
231 | * is still activate. | ||
232 | */ | ||
233 | int __init dma_declare_contiguous(struct device *dev, unsigned long size, | ||
234 | phys_addr_t base, phys_addr_t limit) | ||
235 | { | ||
236 | struct cma_reserved *r = &cma_reserved[cma_reserved_count]; | ||
237 | unsigned long alignment; | ||
238 | |||
239 | pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__, | ||
240 | (unsigned long)size, (unsigned long)base, | ||
241 | (unsigned long)limit); | ||
242 | |||
243 | /* Sanity checks */ | ||
244 | if (cma_reserved_count == ARRAY_SIZE(cma_reserved)) { | ||
245 | pr_err("Not enough slots for CMA reserved regions!\n"); | ||
246 | return -ENOSPC; | ||
247 | } | ||
248 | |||
249 | if (!size) | ||
250 | return -EINVAL; | ||
251 | |||
252 | /* Sanitise input arguments */ | ||
253 | alignment = PAGE_SIZE << max(MAX_ORDER, pageblock_order); | ||
254 | base = ALIGN(base, alignment); | ||
255 | size = ALIGN(size, alignment); | ||
256 | limit &= ~(alignment - 1); | ||
257 | |||
258 | /* Reserve memory */ | ||
259 | if (base) { | ||
260 | if (memblock_is_region_reserved(base, size) || | ||
261 | memblock_reserve(base, size) < 0) { | ||
262 | base = -EBUSY; | ||
263 | goto err; | ||
264 | } | ||
265 | } else { | ||
266 | /* | ||
267 | * Use __memblock_alloc_base() since | ||
268 | * memblock_alloc_base() panic()s. | ||
269 | */ | ||
270 | phys_addr_t addr = __memblock_alloc_base(size, alignment, limit); | ||
271 | if (!addr) { | ||
272 | base = -ENOMEM; | ||
273 | goto err; | ||
274 | } else if (addr + size > ~(unsigned long)0) { | ||
275 | memblock_free(addr, size); | ||
276 | base = -EINVAL; | ||
277 | goto err; | ||
278 | } else { | ||
279 | base = addr; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * Each reserved area must be initialised later, when more kernel | ||
285 | * subsystems (like slab allocator) are available. | ||
286 | */ | ||
287 | r->start = base; | ||
288 | r->size = size; | ||
289 | r->dev = dev; | ||
290 | cma_reserved_count++; | ||
291 | pr_info("CMA: reserved %ld MiB at %08lx\n", size / SZ_1M, | ||
292 | (unsigned long)base); | ||
293 | |||
294 | /* Architecture specific contiguous memory fixup. */ | ||
295 | dma_contiguous_early_fixup(base, size); | ||
296 | return 0; | ||
297 | err: | ||
298 | pr_err("CMA: failed to reserve %ld MiB\n", size / SZ_1M); | ||
299 | return base; | ||
300 | } | ||
301 | |||
302 | /** | ||
303 | * dma_alloc_from_contiguous() - allocate pages from contiguous area | ||
304 | * @dev: Pointer to device for which the allocation is performed. | ||
305 | * @count: Requested number of pages. | ||
306 | * @align: Requested alignment of pages (in PAGE_SIZE order). | ||
307 | * | ||
308 | * This function allocates memory buffer for specified device. It uses | ||
309 | * device specific contiguous memory area if available or the default | ||
310 | * global one. Requires architecture specific get_dev_cma_area() helper | ||
311 | * function. | ||
312 | */ | ||
313 | struct page *dma_alloc_from_contiguous(struct device *dev, int count, | ||
314 | unsigned int align) | ||
315 | { | ||
316 | unsigned long mask, pfn, pageno, start = 0; | ||
317 | struct cma *cma = dev_get_cma_area(dev); | ||
318 | int ret; | ||
319 | |||
320 | if (!cma || !cma->count) | ||
321 | return NULL; | ||
322 | |||
323 | if (align > CONFIG_CMA_ALIGNMENT) | ||
324 | align = CONFIG_CMA_ALIGNMENT; | ||
325 | |||
326 | pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma, | ||
327 | count, align); | ||
328 | |||
329 | if (!count) | ||
330 | return NULL; | ||
331 | |||
332 | mask = (1 << align) - 1; | ||
333 | |||
334 | mutex_lock(&cma_mutex); | ||
335 | |||
336 | for (;;) { | ||
337 | pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count, | ||
338 | start, count, mask); | ||
339 | if (pageno >= cma->count) { | ||
340 | ret = -ENOMEM; | ||
341 | goto error; | ||
342 | } | ||
343 | |||
344 | pfn = cma->base_pfn + pageno; | ||
345 | ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA); | ||
346 | if (ret == 0) { | ||
347 | bitmap_set(cma->bitmap, pageno, count); | ||
348 | break; | ||
349 | } else if (ret != -EBUSY) { | ||
350 | goto error; | ||
351 | } | ||
352 | pr_debug("%s(): memory range at %p is busy, retrying\n", | ||
353 | __func__, pfn_to_page(pfn)); | ||
354 | /* try again with a bit different memory target */ | ||
355 | start = pageno + mask + 1; | ||
356 | } | ||
357 | |||
358 | mutex_unlock(&cma_mutex); | ||
359 | |||
360 | pr_debug("%s(): returned %p\n", __func__, pfn_to_page(pfn)); | ||
361 | return pfn_to_page(pfn); | ||
362 | error: | ||
363 | mutex_unlock(&cma_mutex); | ||
364 | return NULL; | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * dma_release_from_contiguous() - release allocated pages | ||
369 | * @dev: Pointer to device for which the pages were allocated. | ||
370 | * @pages: Allocated pages. | ||
371 | * @count: Number of allocated pages. | ||
372 | * | ||
373 | * This function releases memory allocated by dma_alloc_from_contiguous(). | ||
374 | * It returns false when provided pages do not belong to contiguous area and | ||
375 | * true otherwise. | ||
376 | */ | ||
377 | bool dma_release_from_contiguous(struct device *dev, struct page *pages, | ||
378 | int count) | ||
379 | { | ||
380 | struct cma *cma = dev_get_cma_area(dev); | ||
381 | unsigned long pfn; | ||
382 | |||
383 | if (!cma || !pages) | ||
384 | return false; | ||
385 | |||
386 | pr_debug("%s(page %p)\n", __func__, (void *)pages); | ||
387 | |||
388 | pfn = page_to_pfn(pages); | ||
389 | |||
390 | if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count) | ||
391 | return false; | ||
392 | |||
393 | VM_BUG_ON(pfn + count > cma->base_pfn + cma->count); | ||
394 | |||
395 | mutex_lock(&cma_mutex); | ||
396 | bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count); | ||
397 | free_contig_range(pfn, count); | ||
398 | mutex_unlock(&cma_mutex); | ||
399 | |||
400 | return true; | ||
401 | } | ||
diff --git a/include/asm-generic/dma-contiguous.h b/include/asm-generic/dma-contiguous.h new file mode 100644 index 000000000000..c544356b374b --- /dev/null +++ b/include/asm-generic/dma-contiguous.h | |||
@@ -0,0 +1,28 @@ | |||
1 | #ifndef ASM_DMA_CONTIGUOUS_H | ||
2 | #define ASM_DMA_CONTIGUOUS_H | ||
3 | |||
4 | #ifdef __KERNEL__ | ||
5 | #ifdef CONFIG_CMA | ||
6 | |||
7 | #include <linux/device.h> | ||
8 | #include <linux/dma-contiguous.h> | ||
9 | |||
10 | static inline struct cma *dev_get_cma_area(struct device *dev) | ||
11 | { | ||
12 | if (dev && dev->cma_area) | ||
13 | return dev->cma_area; | ||
14 | return dma_contiguous_default_area; | ||
15 | } | ||
16 | |||
17 | static inline void dev_set_cma_area(struct device *dev, struct cma *cma) | ||
18 | { | ||
19 | if (dev) | ||
20 | dev->cma_area = cma; | ||
21 | if (!dev || !dma_contiguous_default_area) | ||
22 | dma_contiguous_default_area = cma; | ||
23 | } | ||
24 | |||
25 | #endif | ||
26 | #endif | ||
27 | |||
28 | #endif | ||
diff --git a/include/linux/device.h b/include/linux/device.h index 5ad17cccdd71..e3399290436e 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -661,6 +661,10 @@ struct device { | |||
661 | 661 | ||
662 | struct dma_coherent_mem *dma_mem; /* internal for coherent mem | 662 | struct dma_coherent_mem *dma_mem; /* internal for coherent mem |
663 | override */ | 663 | override */ |
664 | #ifdef CONFIG_CMA | ||
665 | struct cma *cma_area; /* contiguous memory area for dma | ||
666 | allocations */ | ||
667 | #endif | ||
664 | /* arch specific additions */ | 668 | /* arch specific additions */ |
665 | struct dev_archdata archdata; | 669 | struct dev_archdata archdata; |
666 | 670 | ||
diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h new file mode 100644 index 000000000000..2f303e4b7ed3 --- /dev/null +++ b/include/linux/dma-contiguous.h | |||
@@ -0,0 +1,110 @@ | |||
1 | #ifndef __LINUX_CMA_H | ||
2 | #define __LINUX_CMA_H | ||
3 | |||
4 | /* | ||
5 | * Contiguous Memory Allocator for DMA mapping framework | ||
6 | * Copyright (c) 2010-2011 by Samsung Electronics. | ||
7 | * Written by: | ||
8 | * Marek Szyprowski <m.szyprowski@samsung.com> | ||
9 | * Michal Nazarewicz <mina86@mina86.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License as | ||
13 | * published by the Free Software Foundation; either version 2 of the | ||
14 | * License or (at your optional) any later version of the license. | ||
15 | */ | ||
16 | |||
17 | /* | ||
18 | * Contiguous Memory Allocator | ||
19 | * | ||
20 | * The Contiguous Memory Allocator (CMA) makes it possible to | ||
21 | * allocate big contiguous chunks of memory after the system has | ||
22 | * booted. | ||
23 | * | ||
24 | * Why is it needed? | ||
25 | * | ||
26 | * Various devices on embedded systems have no scatter-getter and/or | ||
27 | * IO map support and require contiguous blocks of memory to | ||
28 | * operate. They include devices such as cameras, hardware video | ||
29 | * coders, etc. | ||
30 | * | ||
31 | * Such devices often require big memory buffers (a full HD frame | ||
32 | * is, for instance, more then 2 mega pixels large, i.e. more than 6 | ||
33 | * MB of memory), which makes mechanisms such as kmalloc() or | ||
34 | * alloc_page() ineffective. | ||
35 | * | ||
36 | * At the same time, a solution where a big memory region is | ||
37 | * reserved for a device is suboptimal since often more memory is | ||
38 | * reserved then strictly required and, moreover, the memory is | ||
39 | * inaccessible to page system even if device drivers don't use it. | ||
40 | * | ||
41 | * CMA tries to solve this issue by operating on memory regions | ||
42 | * where only movable pages can be allocated from. This way, kernel | ||
43 | * can use the memory for pagecache and when device driver requests | ||
44 | * it, allocated pages can be migrated. | ||
45 | * | ||
46 | * Driver usage | ||
47 | * | ||
48 | * CMA should not be used by the device drivers directly. It is | ||
49 | * only a helper framework for dma-mapping subsystem. | ||
50 | * | ||
51 | * For more information, see kernel-docs in drivers/base/dma-contiguous.c | ||
52 | */ | ||
53 | |||
54 | #ifdef __KERNEL__ | ||
55 | |||
56 | struct cma; | ||
57 | struct page; | ||
58 | struct device; | ||
59 | |||
60 | #ifdef CONFIG_CMA | ||
61 | |||
62 | /* | ||
63 | * There is always at least global CMA area and a few optional device | ||
64 | * private areas configured in kernel .config. | ||
65 | */ | ||
66 | #define MAX_CMA_AREAS (1 + CONFIG_CMA_AREAS) | ||
67 | |||
68 | extern struct cma *dma_contiguous_default_area; | ||
69 | |||
70 | void dma_contiguous_reserve(phys_addr_t addr_limit); | ||
71 | int dma_declare_contiguous(struct device *dev, unsigned long size, | ||
72 | phys_addr_t base, phys_addr_t limit); | ||
73 | |||
74 | struct page *dma_alloc_from_contiguous(struct device *dev, int count, | ||
75 | unsigned int order); | ||
76 | bool dma_release_from_contiguous(struct device *dev, struct page *pages, | ||
77 | int count); | ||
78 | |||
79 | #else | ||
80 | |||
81 | #define MAX_CMA_AREAS (0) | ||
82 | |||
83 | static inline void dma_contiguous_reserve(phys_addr_t limit) { } | ||
84 | |||
85 | static inline | ||
86 | int dma_declare_contiguous(struct device *dev, unsigned long size, | ||
87 | phys_addr_t base, phys_addr_t limit) | ||
88 | { | ||
89 | return -ENOSYS; | ||
90 | } | ||
91 | |||
92 | static inline | ||
93 | struct page *dma_alloc_from_contiguous(struct device *dev, int count, | ||
94 | unsigned int order) | ||
95 | { | ||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | static inline | ||
100 | bool dma_release_from_contiguous(struct device *dev, struct page *pages, | ||
101 | int count) | ||
102 | { | ||
103 | return false; | ||
104 | } | ||
105 | |||
106 | #endif | ||
107 | |||
108 | #endif | ||
109 | |||
110 | #endif | ||