Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for 6.1 kernels (probably works with 5.10+, but untested) #8

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions ion/dma-contiguous.h
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
* Michal Nazarewicz <[email protected]>
*/

/*
* 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 <linux/device.h>
#include <linux/mm.h>

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
4 changes: 2 additions & 2 deletions ion/ion.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions ion/ion_heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion ion/ion_of.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/cma.h>
#include <linux/dma-contiguous.h>
#include "dma-contiguous.h"
#include <linux/io.h>
#include <linux/of_reserved_mem.h>
#include "ion.h"
Expand Down