Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers: add Contiguous Memory Allocator

The Contiguous Memory Allocator is a set of helper functions for DMA
mapping framework that improves allocations of contiguous memory chunks.

CMA grabs memory on system boot, marks it with MIGRATE_CMA migrate type
and gives back to the system. Kernel is allowed to allocate only movable
pages within CMA's managed memory so that it can be used for example for
page cache when DMA mapping do not use it. On
dma_alloc_from_contiguous() request such pages are migrated out of CMA
area to free required contiguous block and fulfill the request. This
allows to allocate large contiguous chunks of memory at any time
assuming that there is enough free memory available in the system.

This code is heavily based on earlier works by Michal Nazarewicz.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Rob Clark <rob.clark@linaro.org>
Tested-by: Ohad Ben-Cohen <ohad@wizery.com>
Tested-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Tested-by: Robert Nelson <robertcnelson@gmail.com>
Tested-by: Barry Song <Baohua.Song@csr.com>

+641
+5
Documentation/kernel-parameters.txt
··· 508 508 Also note the kernel might malfunction if you disable 509 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 516 cmo_free_hint= [PPC] Format: { yes | no } 512 517 Specify whether pages are marked as being inactive 513 518 when they are freed. This is used in CMO environments
+3
arch/Kconfig
··· 142 142 config HAVE_DMA_ATTRS 143 143 bool 144 144 145 + config HAVE_DMA_CONTIGUOUS 146 + bool 147 + 145 148 config USE_GENERIC_SMP_HELPERS 146 149 bool 147 150
+89
drivers/base/Kconfig
··· 192 192 APIs extension; the file's descriptor can then be passed on to other 193 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 284 endmenu
+1
drivers/base/Makefile
··· 6 6 attribute_container.o transport_class.o \ 7 7 topology.o 8 8 obj-$(CONFIG_DEVTMPFS) += devtmpfs.o 9 + obj-$(CONFIG_CMA) += dma-contiguous.o 9 10 obj-y += power/ 10 11 obj-$(CONFIG_HAS_DMA) += dma-mapping.o 11 12 obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
+401
drivers/base/dma-contiguous.c
··· 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 + }
+28
include/asm-generic/dma-contiguous.h
··· 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
+4
include/linux/device.h
··· 661 661 662 662 struct dma_coherent_mem *dma_mem; /* internal for coherent mem 663 663 override */ 664 + #ifdef CONFIG_CMA 665 + struct cma *cma_area; /* contiguous memory area for dma 666 + allocations */ 667 + #endif 664 668 /* arch specific additions */ 665 669 struct dev_archdata archdata; 666 670
+110
include/linux/dma-contiguous.h
··· 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