2 * Device tree based initialization code for reserved memory.
4 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Author: Marek Szyprowski <m.szyprowski@samsung.com>
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.
14 #include <linux/memblock.h>
15 #include <linux/err.h>
17 #include <linux/of_fdt.h>
18 #include <linux/of_platform.h>
20 #include <linux/sizes.h>
21 #include <linux/mm_types.h>
22 #include <linux/dma-contiguous.h>
23 #include <linux/dma-mapping.h>
24 #include <linux/of_reserved_mem.h>
26 #define MAX_RESERVED_REGIONS 16
33 static struct reserved_mem reserved_mem
[MAX_RESERVED_REGIONS
];
34 static int reserved_mem_count
;
36 static int __init
fdt_scan_reserved_mem(unsigned long node
, const char *uname
,
37 int depth
, void *data
)
39 struct reserved_mem
*rmem
= &reserved_mem
[reserved_mem_count
];
40 phys_addr_t base
, size
;
41 int is_cma
, is_reserved
;
46 is_cma
= IS_ENABLED(CONFIG_DMA_CMA
) &&
47 of_flat_dt_is_compatible(node
, "linux,contiguous-memory-region");
48 is_reserved
= of_flat_dt_is_compatible(node
, "reserved-memory-region");
50 if (!is_reserved
&& !is_cma
) {
51 /* ignore node and scan next one */
55 status
= of_get_flat_dt_prop(node
, "status", &len
);
56 if (status
&& strcmp(status
, "okay") != 0) {
57 /* ignore disabled node nad scan next one */
61 prop
= of_get_flat_dt_prop(node
, "reg", &len
);
62 if (!prop
|| (len
< (dt_root_size_cells
+ dt_root_addr_cells
) *
64 pr_err("Reserved mem: node %s, incorrect \"reg\" property\n",
66 /* ignore node and scan next one */
69 base
= dt_mem_next_cell(dt_root_addr_cells
, &prop
);
70 size
= dt_mem_next_cell(dt_root_size_cells
, &prop
);
73 /* ignore node and scan next one */
77 pr_info("Reserved mem: found %s, memory base %lx, size %ld MiB\n",
78 uname
, (unsigned long)base
, (unsigned long)size
/ SZ_1M
);
80 if (reserved_mem_count
== ARRAY_SIZE(reserved_mem
))
85 strlcpy(rmem
->name
, uname
, sizeof(rmem
->name
));
89 if (dma_contiguous_reserve_area(size
, base
, 0, &cma
) == 0) {
92 if (of_get_flat_dt_prop(node
,
93 "linux,default-contiguous-region",
95 dma_contiguous_set_default(cma
);
97 } else if (is_reserved
) {
98 if (memblock_remove(base
, size
) == 0)
101 pr_err("Failed to reserve memory for %s\n", uname
);
107 static struct reserved_mem
*get_dma_memory_region(struct device
*dev
)
109 struct device_node
*node
;
113 node
= of_parse_phandle(dev
->of_node
, "memory-region", 0);
117 name
= kbasename(node
->full_name
);
118 for (i
= 0; i
< reserved_mem_count
; i
++)
119 if (strcmp(name
, reserved_mem
[i
].name
) == 0)
120 return &reserved_mem
[i
];
125 * of_reserved_mem_device_init() - assign reserved memory region to given device
127 * This function assign memory region pointed by "memory-region" device tree
128 * property to the given device.
130 void of_reserved_mem_device_init(struct device
*dev
)
132 struct reserved_mem
*region
= get_dma_memory_region(dev
);
137 dev_set_cma_area(dev
, region
->cma
);
138 pr_info("Assigned CMA %s to %s device\n", region
->name
,
141 if (dma_declare_coherent_memory(dev
, region
->base
, region
->base
,
142 region
->size
, DMA_MEMORY_MAP
| DMA_MEMORY_EXCLUSIVE
) != 0)
143 pr_info("Declared reserved memory %s to %s device\n",
144 region
->name
, dev_name(dev
));
149 * of_reserved_mem_device_release() - release reserved memory device structures
151 * This function releases structures allocated for memory region handling for
154 void of_reserved_mem_device_release(struct device
*dev
)
156 struct reserved_mem
*region
= get_dma_memory_region(dev
);
157 if (!region
&& !region
->cma
)
158 dma_release_declared_memory(dev
);
162 * early_init_dt_scan_reserved_mem() - create reserved memory regions
164 * This function grabs memory from early allocator for device exclusive use
165 * defined in device tree structures. It should be called by arch specific code
166 * once the early allocator (memblock) has been activated and all other
167 * subsystems have already allocated/reserved memory.
169 void __init
early_init_dt_scan_reserved_mem(void)
171 of_scan_flat_dt_by_path("/memory/reserved-memory",
172 fdt_scan_reserved_mem
, NULL
);