aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/dma-contiguous.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/dma-contiguous.c')
-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