1 // SPDX-License-Identifier: GPL-2.0 2 /** 3 * PCI Endpoint *Controller* Address Space Management 4 * 5 * Copyright (C) 2017 Texas Instruments 6 * Author: Kishon Vijay Abraham I <kishon@ti.com> 7 */ 8 9 #include <linux/io.h> 10 #include <linux/module.h> 11 #include <linux/slab.h> 12 13 #include <linux/pci-epc.h> 14 15 /** 16 * pci_epc_mem_get_order() - determine the allocation order of a memory size 17 * @mem: address space of the endpoint controller 18 * @size: the size for which to get the order 19 * 20 * Reimplement get_order() for mem->page_size since the generic get_order 21 * always gets order with a constant PAGE_SIZE. 22 */ 23 static int pci_epc_mem_get_order(struct pci_epc_mem *mem, size_t size) 24 { 25 int order; 26 unsigned int page_shift = ilog2(mem->page_size); 27 28 size--; 29 size >>= page_shift; 30 #if BITS_PER_LONG == 32 31 order = fls(size); 32 #else 33 order = fls64(size); 34 #endif 35 return order; 36 } 37 38 /** 39 * __pci_epc_mem_init() - initialize the pci_epc_mem structure 40 * @epc: the EPC device that invoked pci_epc_mem_init 41 * @phys_base: the physical address of the base 42 * @size: the size of the address space 43 * @page_size: size of each page 44 * 45 * Invoke to initialize the pci_epc_mem structure used by the 46 * endpoint functions to allocate mapped PCI address. 47 */ 48 int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size, 49 size_t page_size) 50 { 51 int ret; 52 struct pci_epc_mem *mem; 53 unsigned long *bitmap; 54 unsigned int page_shift; 55 int pages; 56 int bitmap_size; 57 58 if (page_size < PAGE_SIZE) 59 page_size = PAGE_SIZE; 60 61 page_shift = ilog2(page_size); 62 pages = size >> page_shift; 63 bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); 64 65 mem = kzalloc(sizeof(*mem), GFP_KERNEL); 66 if (!mem) { 67 ret = -ENOMEM; 68 goto err; 69 } 70 71 bitmap = kzalloc(bitmap_size, GFP_KERNEL); 72 if (!bitmap) { 73 ret = -ENOMEM; 74 goto err_mem; 75 } 76 77 mem->bitmap = bitmap; 78 mem->phys_base = phys_base; 79 mem->page_size = page_size; 80 mem->pages = pages; 81 mem->size = size; 82 mutex_init(&mem->lock); 83 84 epc->mem = mem; 85 86 return 0; 87 88 err_mem: 89 kfree(mem); 90 91 err: 92 return ret; 93 } 94 EXPORT_SYMBOL_GPL(__pci_epc_mem_init); 95 96 /** 97 * pci_epc_mem_exit() - cleanup the pci_epc_mem structure 98 * @epc: the EPC device that invoked pci_epc_mem_exit 99 * 100 * Invoke to cleanup the pci_epc_mem structure allocated in 101 * pci_epc_mem_init(). 102 */ 103 void pci_epc_mem_exit(struct pci_epc *epc) 104 { 105 struct pci_epc_mem *mem = epc->mem; 106 107 epc->mem = NULL; 108 kfree(mem->bitmap); 109 kfree(mem); 110 } 111 EXPORT_SYMBOL_GPL(pci_epc_mem_exit); 112 113 /** 114 * pci_epc_mem_alloc_addr() - allocate memory address from EPC addr space 115 * @epc: the EPC device on which memory has to be allocated 116 * @phys_addr: populate the allocated physical address here 117 * @size: the size of the address space that has to be allocated 118 * 119 * Invoke to allocate memory address from the EPC address space. This 120 * is usually done to map the remote RC address into the local system. 121 */ 122 void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, 123 phys_addr_t *phys_addr, size_t size) 124 { 125 int pageno; 126 void __iomem *virt_addr = NULL; 127 struct pci_epc_mem *mem = epc->mem; 128 unsigned int page_shift = ilog2(mem->page_size); 129 int order; 130 131 size = ALIGN(size, mem->page_size); 132 order = pci_epc_mem_get_order(mem, size); 133 134 mutex_lock(&mem->lock); 135 pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order); 136 if (pageno < 0) 137 goto ret; 138 139 *phys_addr = mem->phys_base + ((phys_addr_t)pageno << page_shift); 140 virt_addr = ioremap(*phys_addr, size); 141 if (!virt_addr) 142 bitmap_release_region(mem->bitmap, pageno, order); 143 144 ret: 145 mutex_unlock(&mem->lock); 146 return virt_addr; 147 } 148 EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr); 149 150 /** 151 * pci_epc_mem_free_addr() - free the allocated memory address 152 * @epc: the EPC device on which memory was allocated 153 * @phys_addr: the allocated physical address 154 * @virt_addr: virtual address of the allocated mem space 155 * @size: the size of the allocated address space 156 * 157 * Invoke to free the memory allocated using pci_epc_mem_alloc_addr. 158 */ 159 void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr, 160 void __iomem *virt_addr, size_t size) 161 { 162 int pageno; 163 struct pci_epc_mem *mem = epc->mem; 164 unsigned int page_shift = ilog2(mem->page_size); 165 int order; 166 167 iounmap(virt_addr); 168 pageno = (phys_addr - mem->phys_base) >> page_shift; 169 size = ALIGN(size, mem->page_size); 170 order = pci_epc_mem_get_order(mem, size); 171 mutex_lock(&mem->lock); 172 bitmap_release_region(mem->bitmap, pageno, order); 173 mutex_unlock(&mem->lock); 174 } 175 EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr); 176 177 MODULE_DESCRIPTION("PCI EPC Address Space Management"); 178 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>"); 179 MODULE_LICENSE("GPL v2"); 180