aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2014-10-13 18:51:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 20:18:12 -0400
commitde9e14eebf33a60712a52a0bc6e08c043c0aba53 (patch)
tree7b681bf9d5cb6a7909c8d9090aaa868d3e22ccf2 /drivers/base
parent7bfa5ab6fa1b18f53fb94f922e107e6fbdc5e485 (diff)
drivers: dma-contiguous: add initialization from device tree
Add a function to create CMA region from previously reserved memory and add support for handling 'shared-dma-pool' reserved-memory device tree nodes. Based on previous code provided by Josh Cartwright <joshc@codeaurora.org> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Michal Nazarewicz <mina86@mina86.com> Cc: Grant Likely <grant.likely@linaro.org> Cc: Laura Abbott <lauraa@codeaurora.org> Cc: Josh Cartwright <joshc@codeaurora.org> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/dma-contiguous.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 6606abdf880c..473ff4892401 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -211,3 +211,69 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
211{ 211{
212 return cma_release(dev_get_cma_area(dev), pages, count); 212 return cma_release(dev_get_cma_area(dev), pages, count);
213} 213}
214
215/*
216 * Support for reserved memory regions defined in device tree
217 */
218#ifdef CONFIG_OF_RESERVED_MEM
219#include <linux/of.h>
220#include <linux/of_fdt.h>
221#include <linux/of_reserved_mem.h>
222
223#undef pr_fmt
224#define pr_fmt(fmt) fmt
225
226static void rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev)
227{
228 dev_set_cma_area(dev, rmem->priv);
229}
230
231static void rmem_cma_device_release(struct reserved_mem *rmem,
232 struct device *dev)
233{
234 dev_set_cma_area(dev, NULL);
235}
236
237static const struct reserved_mem_ops rmem_cma_ops = {
238 .device_init = rmem_cma_device_init,
239 .device_release = rmem_cma_device_release,
240};
241
242static int __init rmem_cma_setup(struct reserved_mem *rmem)
243{
244 phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order);
245 phys_addr_t mask = align - 1;
246 unsigned long node = rmem->fdt_node;
247 struct cma *cma;
248 int err;
249
250 if (!of_get_flat_dt_prop(node, "reusable", NULL) ||
251 of_get_flat_dt_prop(node, "no-map", NULL))
252 return -EINVAL;
253
254 if ((rmem->base & mask) || (rmem->size & mask)) {
255 pr_err("Reserved memory: incorrect alignment of CMA region\n");
256 return -EINVAL;
257 }
258
259 err = cma_init_reserved_mem(rmem->base, rmem->size, 0, &cma);
260 if (err) {
261 pr_err("Reserved memory: unable to setup CMA region\n");
262 return err;
263 }
264 /* Architecture specific contiguous memory fixup. */
265 dma_contiguous_early_fixup(rmem->base, rmem->size);
266
267 if (of_get_flat_dt_prop(node, "linux,cma-default", NULL))
268 dma_contiguous_set_default(cma);
269
270 rmem->ops = &rmem_cma_ops;
271 rmem->priv = cma;
272
273 pr_info("Reserved memory: created CMA memory pool at %pa, size %ld MiB\n",
274 &rmem->base, (unsigned long)rmem->size / SZ_1M);
275
276 return 0;
277}
278RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup);
279#endif