diff --git a/ion/dma-contiguous.h b/ion/dma-contiguous.h new file mode 100644 index 0000000..03f8e98 --- /dev/null +++ b/ion/dma-contiguous.h @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef __LINUX_CMA_H +#define __LINUX_CMA_H + +/* + * Contiguous Memory Allocator for DMA mapping framework + * Copyright (c) 2010-2011 by Samsung Electronics. + * Written by: + * Marek Szyprowski + * Michal Nazarewicz + */ + +/* + * Contiguous Memory Allocator + * + * The Contiguous Memory Allocator (CMA) makes it possible to + * allocate big contiguous chunks of memory after the system has + * booted. + * + * Why is it needed? + * + * Various devices on embedded systems have no scatter-getter and/or + * IO map support and require contiguous blocks of memory to + * operate. They include devices such as cameras, hardware video + * coders, etc. + * + * Such devices often require big memory buffers (a full HD frame + * is, for instance, more then 2 mega pixels large, i.e. more than 6 + * MB of memory), which makes mechanisms such as kmalloc() or + * alloc_page() ineffective. + * + * At the same time, a solution where a big memory region is + * reserved for a device is suboptimal since often more memory is + * reserved then strictly required and, moreover, the memory is + * inaccessible to page system even if device drivers don't use it. + * + * CMA tries to solve this issue by operating on memory regions + * where only movable pages can be allocated from. This way, kernel + * can use the memory for pagecache and when device driver requests + * it, allocated pages can be migrated. + * + * Driver usage + * + * CMA should not be used by the device drivers directly. It is + * only a helper framework for dma-mapping subsystem. + * + * For more information, see kernel-docs in kernel/dma/contiguous.c + */ + +#ifdef __KERNEL__ + +#include +#include + +struct cma; +struct page; + +#ifdef CONFIG_DMA_CMA + +extern struct cma *dma_contiguous_default_area; + +static inline struct cma *dev_get_cma_area(struct device *dev) +{ + if (dev && dev->cma_area) + return dev->cma_area; + return dma_contiguous_default_area; +} + +static inline void dev_set_cma_area(struct device *dev, struct cma *cma) +{ + if (dev) + dev->cma_area = cma; +} + +static inline void dma_contiguous_set_default(struct cma *cma) +{ + dma_contiguous_default_area = cma; +} + +void dma_contiguous_reserve(phys_addr_t addr_limit); + +int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, + phys_addr_t limit, struct cma **res_cma, + bool fixed); + +/** + * dma_declare_contiguous() - reserve area for contiguous memory handling + * for particular device + * @dev: Pointer to device structure. + * @size: Size of the reserved memory. + * @base: Start address of the reserved memory (optional, 0 for any). + * @limit: End address of the reserved memory (optional, 0 for any). + * + * This function reserves memory for specified device. It should be + * called by board specific code when early allocator (memblock or bootmem) + * is still activate. + */ + +static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size, + phys_addr_t base, phys_addr_t limit) +{ + struct cma *cma; + int ret; + ret = dma_contiguous_reserve_area(size, base, limit, &cma, true); + if (ret == 0) + dev_set_cma_area(dev, cma); + + return ret; +} + +struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, + unsigned int order, bool no_warn); +bool dma_release_from_contiguous(struct device *dev, struct page *pages, + int count); +struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp); +void dma_free_contiguous(struct device *dev, struct page *page, size_t size); + +#else + +static inline struct cma *dev_get_cma_area(struct device *dev) +{ + return NULL; +} + +static inline void dev_set_cma_area(struct device *dev, struct cma *cma) { } + +static inline void dma_contiguous_set_default(struct cma *cma) { } + +static inline void dma_contiguous_reserve(phys_addr_t limit) { } + +static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base, + phys_addr_t limit, struct cma **res_cma, + bool fixed) +{ + return -ENOSYS; +} + +static inline +int dma_declare_contiguous(struct device *dev, phys_addr_t size, + phys_addr_t base, phys_addr_t limit) +{ + return -ENOSYS; +} + +static inline +struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, + unsigned int order, bool no_warn) +{ + return NULL; +} + +static inline +bool dma_release_from_contiguous(struct device *dev, struct page *pages, + int count) +{ + return false; +} + +/* Use fallback alloc() and free() when CONFIG_DMA_CMA=n */ +static inline struct page *dma_alloc_contiguous(struct device *dev, size_t size, + gfp_t gfp) +{ + return NULL; +} + +static inline void dma_free_contiguous(struct device *dev, struct page *page, + size_t size) +{ + __free_pages(page, get_order(size)); +} + +#endif + +#endif + +#endif diff --git a/ion/ion.c b/ion/ion.c index faa2e0c..2f98208 100644 --- a/ion/ion.c +++ b/ion/ion.c @@ -1023,8 +1023,8 @@ static struct dma_buf_ops dma_buf_ops = { .release = ion_dma_buf_release, .begin_cpu_access = ion_dma_buf_begin_cpu_access, .end_cpu_access = ion_dma_buf_end_cpu_access, - .map = ion_dma_buf_kmap, - .unmap = ion_dma_buf_kunmap, +// .map = ion_dma_buf_kmap, +// .unmap = ion_dma_buf_kunmap, }; static struct dma_buf *__ion_share_dma_buf(struct ion_client *client, diff --git a/ion/ion_heap.c b/ion/ion_heap.c index 8e3bd3a..0bd003d 100644 --- a/ion/ion_heap.c +++ b/ion/ion_heap.c @@ -106,7 +106,7 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) { - void *addr = vm_map_ram(pages, num, -1, pgprot); + void *addr = vm_map_ram(pages, num, -1); if (!addr) return -ENOMEM; @@ -313,7 +313,7 @@ void ion_heap_init_shrinker(struct ion_heap *heap) heap->shrinker.scan_objects = ion_heap_shrink_scan; heap->shrinker.seeks = DEFAULT_SEEKS; heap->shrinker.batch = 0; - register_shrinker(&heap->shrinker); + register_shrinker(&heap->shrinker, "ion_heap"); } struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data) diff --git a/ion/ion_of.c b/ion/ion_of.c index 46b2bb9..3a3b7f0 100644 --- a/ion/ion_of.c +++ b/ion/ion_of.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include "dma-contiguous.h" #include #include #include "ion.h"