Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / include / linux / dma-contiguous.h
diff --git a/kernel/include/linux/dma-contiguous.h b/kernel/include/linux/dma-contiguous.h
new file mode 100644 (file)
index 0000000..569bbd0
--- /dev/null
@@ -0,0 +1,164 @@
+#ifndef __LINUX_CMA_H
+#define __LINUX_CMA_H
+
+/*
+ * Contiguous Memory Allocator for DMA mapping framework
+ * Copyright (c) 2010-2011 by Samsung Electronics.
+ * Written by:
+ *     Marek Szyprowski <m.szyprowski@samsung.com>
+ *     Michal Nazarewicz <mina86@mina86.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ */
+
+/*
+ * Contiguous Memory Allocator
+ *
+ *   The Contiguous Memory Allocator (CMA) makes it possible to
+ *   allocate big contiguous chunks of memory after the system has
+ *   booted.
+ *
+ * Why is it needed?
+ *
+ *   Various devices on embedded systems have no scatter-getter and/or
+ *   IO map support and require contiguous blocks of memory to
+ *   operate.  They include devices such as cameras, hardware video
+ *   coders, etc.
+ *
+ *   Such devices often require big memory buffers (a full HD frame
+ *   is, for instance, more then 2 mega pixels large, i.e. more than 6
+ *   MB of memory), which makes mechanisms such as kmalloc() or
+ *   alloc_page() ineffective.
+ *
+ *   At the same time, a solution where a big memory region is
+ *   reserved for a device is suboptimal since often more memory is
+ *   reserved then strictly required and, moreover, the memory is
+ *   inaccessible to page system even if device drivers don't use it.
+ *
+ *   CMA tries to solve this issue by operating on memory regions
+ *   where only movable pages can be allocated from.  This way, kernel
+ *   can use the memory for pagecache and when device driver requests
+ *   it, allocated pages can be migrated.
+ *
+ * Driver usage
+ *
+ *   CMA should not be used by the device drivers directly. It is
+ *   only a helper framework for dma-mapping subsystem.
+ *
+ *   For more information, see kernel-docs in drivers/base/dma-contiguous.c
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/device.h>
+
+struct cma;
+struct page;
+
+#ifdef CONFIG_DMA_CMA
+
+extern struct cma *dma_contiguous_default_area;
+
+static inline struct cma *dev_get_cma_area(struct device *dev)
+{
+       if (dev && dev->cma_area)
+               return dev->cma_area;
+       return dma_contiguous_default_area;
+}
+
+static inline void dev_set_cma_area(struct device *dev, struct cma *cma)
+{
+       if (dev)
+               dev->cma_area = cma;
+}
+
+static inline void dma_contiguous_set_default(struct cma *cma)
+{
+       dma_contiguous_default_area = cma;
+}
+
+void dma_contiguous_reserve(phys_addr_t addr_limit);
+
+int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
+                                      phys_addr_t limit, struct cma **res_cma,
+                                      bool fixed);
+
+/**
+ * dma_declare_contiguous() - reserve area for contiguous memory handling
+ *                           for particular device
+ * @dev:   Pointer to device structure.
+ * @size:  Size of the reserved memory.
+ * @base:  Start address of the reserved memory (optional, 0 for any).
+ * @limit: End address of the reserved memory (optional, 0 for any).
+ *
+ * This function reserves memory for specified device. It should be
+ * called by board specific code when early allocator (memblock or bootmem)
+ * is still activate.
+ */
+
+static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size,
+                                        phys_addr_t base, phys_addr_t limit)
+{
+       struct cma *cma;
+       int ret;
+       ret = dma_contiguous_reserve_area(size, base, limit, &cma, true);
+       if (ret == 0)
+               dev_set_cma_area(dev, cma);
+
+       return ret;
+}
+
+struct page *dma_alloc_from_contiguous(struct device *dev, int count,
+                                      unsigned int order);
+bool dma_release_from_contiguous(struct device *dev, struct page *pages,
+                                int count);
+
+#else
+
+static inline struct cma *dev_get_cma_area(struct device *dev)
+{
+       return NULL;
+}
+
+static inline void dev_set_cma_area(struct device *dev, struct cma *cma) { }
+
+static inline void dma_contiguous_set_default(struct cma *cma) { }
+
+static inline void dma_contiguous_reserve(phys_addr_t limit) { }
+
+static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
+                                      phys_addr_t limit, struct cma **res_cma,
+                                      bool fixed)
+{
+       return -ENOSYS;
+}
+
+static inline
+int dma_declare_contiguous(struct device *dev, phys_addr_t size,
+                          phys_addr_t base, phys_addr_t limit)
+{
+       return -ENOSYS;
+}
+
+static inline
+struct page *dma_alloc_from_contiguous(struct device *dev, int count,
+                                      unsigned int order)
+{
+       return NULL;
+}
+
+static inline
+bool dma_release_from_contiguous(struct device *dev, struct page *pages,
+                                int count)
+{
+       return false;
+}
+
+#endif
+
+#endif
+
+#endif