Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3)  * Copyright (c) 2014 The Linux Foundation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5) #include <linux/dma-map-ops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) struct page **dma_common_find_pages(void *cpu_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) 	struct vm_struct *area = find_vm_area(cpu_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 	if (!area || area->flags != VM_DMA_COHERENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) 	return area->pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)  * Remaps an array of PAGE_SIZE pages into another vm_area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)  * Cannot be used in non-sleeping contexts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) void *dma_common_pages_remap(struct page **pages, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 			 pgprot_t prot, const void *caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 	void *vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 	vaddr = vmap(pages, PAGE_ALIGN(size) >> PAGE_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 		     VM_DMA_COHERENT, prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 	if (vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 		find_vm_area(vaddr)->pages = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 	return vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)  * Remaps an allocated contiguous region into another vm_area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)  * Cannot be used in non-sleeping contexts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) void *dma_common_contiguous_remap(struct page *page, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 			pgprot_t prot, const void *caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 	int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 	struct page **pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 	void *vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 	pages = kmalloc_array(count, sizeof(struct page *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 	if (!pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 	for (i = 0; i < count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 		pages[i] = nth_page(page, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 	vaddr = vmap(pages, count, VM_DMA_COHERENT, prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 	kfree(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 	return vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)  * Unmaps a range previously mapped by dma_common_*_remap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) void dma_common_free_remap(void *cpu_addr, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 	struct vm_struct *area = find_vm_area(cpu_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 	if (!area || area->flags != VM_DMA_COHERENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 		WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 	unmap_kernel_range((unsigned long)cpu_addr, PAGE_ALIGN(size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 	vunmap(cpu_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }