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)  * PCI Endpoint *Controller* Address Space Management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2017 Texas Instruments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Author: Kishon Vijay Abraham I <kishon@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/pci-epc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * pci_epc_mem_get_order() - determine the allocation order of a memory size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * @mem: address space of the endpoint controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * @size: the size for which to get the order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * Reimplement get_order() for mem->page_size since the generic get_order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * always gets order with a constant PAGE_SIZE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) static int pci_epc_mem_get_order(struct pci_epc_mem *mem, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	int order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	unsigned int page_shift = ilog2(mem->window.page_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	size >>= page_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #if BITS_PER_LONG == 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	order = fls(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	order = fls64(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	return order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * pci_epc_multi_mem_init() - initialize the pci_epc_mem structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * @epc: the EPC device that invoked pci_epc_mem_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * @windows: pointer to windows supported by the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * @num_windows: number of windows device supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * Invoke to initialize the pci_epc_mem structure used by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * endpoint functions to allocate mapped PCI address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) int pci_epc_multi_mem_init(struct pci_epc *epc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 			   struct pci_epc_mem_window *windows,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 			   unsigned int num_windows)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	struct pci_epc_mem *mem = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	unsigned long *bitmap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	unsigned int page_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	size_t page_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	int bitmap_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	int pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	epc->num_windows = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	if (!windows || !num_windows)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	epc->windows = kcalloc(num_windows, sizeof(*epc->windows), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (!epc->windows)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	for (i = 0; i < num_windows; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		page_size = windows[i].page_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		if (page_size < PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			page_size = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		page_shift = ilog2(page_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		pages = windows[i].size >> page_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		mem = kzalloc(sizeof(*mem), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		if (!mem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			goto err_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		bitmap = kzalloc(bitmap_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		if (!bitmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			kfree(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 			goto err_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		mem->window.phys_base = windows[i].phys_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		mem->window.size = windows[i].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		mem->window.page_size = page_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		mem->bitmap = bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		mem->pages = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		mutex_init(&mem->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		epc->windows[i] = mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	epc->mem = epc->windows[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	epc->num_windows = num_windows;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) err_mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	for (; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		mem = epc->windows[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		kfree(mem->bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		kfree(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	kfree(epc->windows);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) EXPORT_SYMBOL_GPL(pci_epc_multi_mem_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		     size_t size, size_t page_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	struct pci_epc_mem_window mem_window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	mem_window.phys_base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	mem_window.size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	mem_window.page_size = page_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	return pci_epc_multi_mem_init(epc, &mem_window, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) EXPORT_SYMBOL_GPL(pci_epc_mem_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * pci_epc_mem_exit() - cleanup the pci_epc_mem structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * @epc: the EPC device that invoked pci_epc_mem_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * Invoke to cleanup the pci_epc_mem structure allocated in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * pci_epc_mem_init().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) void pci_epc_mem_exit(struct pci_epc *epc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	struct pci_epc_mem *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	if (!epc->num_windows)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	for (i = 0; i < epc->num_windows; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		mem = epc->windows[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		kfree(mem->bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		kfree(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	kfree(epc->windows);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	epc->windows = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	epc->mem = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	epc->num_windows = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * pci_epc_mem_alloc_addr() - allocate memory address from EPC addr space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  * @epc: the EPC device on which memory has to be allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  * @phys_addr: populate the allocated physical address here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  * @size: the size of the address space that has to be allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  * Invoke to allocate memory address from the EPC address space. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * is usually done to map the remote RC address into the local system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 				     phys_addr_t *phys_addr, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	void __iomem *virt_addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	struct pci_epc_mem *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	unsigned int page_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	size_t align_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	int pageno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	int order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	for (i = 0; i < epc->num_windows; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		mem = epc->windows[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		mutex_lock(&mem->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		align_size = ALIGN(size, mem->window.page_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		order = pci_epc_mem_get_order(mem, align_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		pageno = bitmap_find_free_region(mem->bitmap, mem->pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 						 order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		if (pageno >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			page_shift = ilog2(mem->window.page_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			*phys_addr = mem->window.phys_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 				((phys_addr_t)pageno << page_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 			virt_addr = ioremap(*phys_addr, align_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			if (!virt_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 				bitmap_release_region(mem->bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 						      pageno, order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 				mutex_unlock(&mem->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			mutex_unlock(&mem->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			return virt_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		mutex_unlock(&mem->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	return virt_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static struct pci_epc_mem *pci_epc_get_matching_window(struct pci_epc *epc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 						       phys_addr_t phys_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	struct pci_epc_mem *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	for (i = 0; i < epc->num_windows; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		mem = epc->windows[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		if (phys_addr >= mem->window.phys_base &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		    phys_addr < (mem->window.phys_base + mem->window.size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			return mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  * pci_epc_mem_free_addr() - free the allocated memory address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  * @epc: the EPC device on which memory was allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  * @phys_addr: the allocated physical address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  * @virt_addr: virtual address of the allocated mem space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  * @size: the size of the allocated address space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  * Invoke to free the memory allocated using pci_epc_mem_alloc_addr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			   void __iomem *virt_addr, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	struct pci_epc_mem *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	unsigned int page_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	size_t page_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	int pageno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	int order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	mem = pci_epc_get_matching_window(epc, phys_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	if (!mem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		pr_err("failed to get matching window\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	page_size = mem->window.page_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	page_shift = ilog2(page_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	iounmap(virt_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	pageno = (phys_addr - mem->window.phys_base) >> page_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	size = ALIGN(size, page_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	order = pci_epc_mem_get_order(mem, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	mutex_lock(&mem->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	bitmap_release_region(mem->bitmap, pageno, order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	mutex_unlock(&mem->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) MODULE_DESCRIPTION("PCI EPC Address Space Management");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) MODULE_LICENSE("GPL v2");