|
42 | 42 | #include <linux/memblock.h> |
43 | 43 | #include <linux/err.h> |
44 | 44 | #include <linux/sizes.h> |
45 | | -#include <linux/dma-buf/heaps/cma.h> |
46 | 45 | #include <linux/dma-map-ops.h> |
47 | 46 | #include <linux/cma.h> |
48 | 47 | #include <linux/nospec.h> |
|
53 | 52 | #define CMA_SIZE_MBYTES 0 |
54 | 53 | #endif |
55 | 54 |
|
56 | | -struct cma *dma_contiguous_default_area; |
| 55 | +static struct cma *dma_contiguous_areas[MAX_CMA_AREAS]; |
| 56 | +static unsigned int dma_contiguous_areas_num; |
| 57 | + |
| 58 | +static int dma_contiguous_insert_area(struct cma *cma) |
| 59 | +{ |
| 60 | + if (dma_contiguous_areas_num >= ARRAY_SIZE(dma_contiguous_areas)) |
| 61 | + return -EINVAL; |
| 62 | + |
| 63 | + dma_contiguous_areas[dma_contiguous_areas_num++] = cma; |
| 64 | + |
| 65 | + return 0; |
| 66 | +} |
| 67 | + |
| 68 | +/** |
| 69 | + * dma_contiguous_get_area_by_idx() - Get contiguous area at given index |
| 70 | + * @idx: index of the area we query |
| 71 | + * |
| 72 | + * Queries for the contiguous area located at index @idx. |
| 73 | + * |
| 74 | + * Returns: |
| 75 | + * A pointer to the requested contiguous area, or NULL otherwise. |
| 76 | + */ |
| 77 | +struct cma *dma_contiguous_get_area_by_idx(unsigned int idx) |
| 78 | +{ |
| 79 | + if (idx >= dma_contiguous_areas_num) |
| 80 | + return NULL; |
| 81 | + |
| 82 | + return dma_contiguous_areas[idx]; |
| 83 | +} |
| 84 | +EXPORT_SYMBOL_GPL(dma_contiguous_get_area_by_idx); |
| 85 | + |
| 86 | +static struct cma *dma_contiguous_default_area; |
57 | 87 |
|
58 | 88 | /* |
59 | 89 | * Default global CMA area size can be defined in kernel's .config. |
@@ -91,6 +121,15 @@ static int __init early_cma(char *p) |
91 | 121 | } |
92 | 122 | early_param("cma", early_cma); |
93 | 123 |
|
| 124 | +struct cma *dev_get_cma_area(struct device *dev) |
| 125 | +{ |
| 126 | + if (dev && dev->cma_area) |
| 127 | + return dev->cma_area; |
| 128 | + |
| 129 | + return dma_contiguous_default_area; |
| 130 | +} |
| 131 | +EXPORT_SYMBOL_GPL(dev_get_cma_area); |
| 132 | + |
94 | 133 | #ifdef CONFIG_DMA_NUMA_CMA |
95 | 134 |
|
96 | 135 | static struct cma *dma_contiguous_numa_area[MAX_NUMNODES]; |
@@ -254,9 +293,24 @@ void __init dma_contiguous_reserve(phys_addr_t limit) |
254 | 293 | if (ret) |
255 | 294 | return; |
256 | 295 |
|
257 | | - ret = dma_heap_cma_register_heap(dma_contiguous_default_area); |
| 296 | + /* |
| 297 | + * We need to insert the new area in our list to avoid |
| 298 | + * any inconsistencies between having the default area |
| 299 | + * listed in the DT or not. |
| 300 | + * |
| 301 | + * The DT case is handled by rmem_cma_setup() and will |
| 302 | + * always insert all its areas in our list. However, if |
| 303 | + * it didn't run (because OF_RESERVED_MEM isn't set, or |
| 304 | + * there's no DT region specified), then we don't have a |
| 305 | + * default area yet, and no area in our list. |
| 306 | + * |
| 307 | + * This block creates the default area in such a case, |
| 308 | + * but we also need to insert it in our list to avoid |
| 309 | + * having a default area but an empty list. |
| 310 | + */ |
| 311 | + ret = dma_contiguous_insert_area(dma_contiguous_default_area); |
258 | 312 | if (ret) |
259 | | - pr_warn("Couldn't register default CMA heap."); |
| 313 | + pr_warn("Couldn't queue default CMA region for heap creation."); |
260 | 314 | } |
261 | 315 | } |
262 | 316 |
|
@@ -529,9 +583,9 @@ static int __init rmem_cma_setup(unsigned long node, struct reserved_mem *rmem) |
529 | 583 | pr_info("Reserved memory: created CMA memory pool at %pa, size %ld MiB\n", |
530 | 584 | &rmem->base, (unsigned long)rmem->size / SZ_1M); |
531 | 585 |
|
532 | | - ret = dma_heap_cma_register_heap(cma); |
| 586 | + ret = dma_contiguous_insert_area(cma); |
533 | 587 | if (ret) |
534 | | - pr_warn("Couldn't register CMA heap."); |
| 588 | + pr_warn("Couldn't store CMA reserved area."); |
535 | 589 |
|
536 | 590 | return 0; |
537 | 591 | } |
|
0 commit comments