Add dma_heap_coherent_register() call within reserved memory DMA setup logic for non-reusable DT nodes.
Signed-off-by: Albert Esteve aesteve@redhat.com --- kernel/dma/coherent.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c index 1147497bc512c..d0d0979ffb153 100644 --- a/kernel/dma/coherent.c +++ b/kernel/dma/coherent.c @@ -9,6 +9,7 @@ #include <linux/module.h> #include <linux/dma-direct.h> #include <linux/dma-map-ops.h> +#include <linux/dma-heap.h>
struct dma_coherent_mem { void *virt_base; @@ -334,6 +335,31 @@ static phys_addr_t dma_reserved_default_memory_base __initdata; static phys_addr_t dma_reserved_default_memory_size __initdata; #endif
+#define MAX_COHERENT_REGIONS 64 + +static struct reserved_mem *rmem_coherent_areas[MAX_COHERENT_REGIONS]; +static unsigned int rmem_coherent_areas_num; + +static int rmem_coherent_insert_area(struct reserved_mem *rmem) +{ + if (rmem_coherent_areas_num >= MAX_COHERENT_REGIONS) { + pr_warn("Deferred heap areas list full, dropping %s\n", + rmem->name ? rmem->name : "unknown"); + return -EINVAL; + } + rmem_coherent_areas[rmem_coherent_areas_num++] = rmem; + return 0; +} + +struct reserved_mem *dma_coherent_get_reserved_region(unsigned int idx) +{ + if (idx >= rmem_coherent_areas_num) + return NULL; + + return rmem_coherent_areas[idx]; +} +EXPORT_SYMBOL_GPL(dma_coherent_get_reserved_region); + static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev) { struct dma_coherent_mem *mem = rmem->priv; @@ -393,6 +419,14 @@ static int __init rmem_dma_setup(struct reserved_mem *rmem) rmem->ops = &rmem_dma_ops; pr_info("Reserved memory: created DMA memory pool at %pa, size %ld MiB\n", &rmem->base, (unsigned long)rmem->size / SZ_1M); + + if (IS_ENABLED(CONFIG_DMABUF_HEAPS_COHERENT)) { + int ret = rmem_coherent_insert_area(rmem); + + if (ret) + pr_warn("Reserved memory: failed to store coherent area for %s (%d)\n", + rmem->name ? rmem->name : "unknown", ret); + } return 0; }