2 * PCI Endpoint *Controller* Address Space Management
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <linux/module.h>
22 #include <linux/slab.h>
24 #include <linux/pci-epc.h>
27 * pci_epc_mem_init() - initialize the pci_epc_mem structure
28 * @epc: the EPC device that invoked pci_epc_mem_init
29 * @phys_base: the physical address of the base
30 * @size: the size of the address space
32 * Invoke to initialize the pci_epc_mem structure used by the
33 * endpoint functions to allocate mapped PCI address.
35 int pci_epc_mem_init(struct pci_epc
*epc
, phys_addr_t phys_base
, size_t size
)
38 struct pci_epc_mem
*mem
;
39 unsigned long *bitmap
;
40 int pages
= size
>> PAGE_SHIFT
;
41 int bitmap_size
= BITS_TO_LONGS(pages
) * sizeof(long);
43 mem
= kzalloc(sizeof(*mem
), GFP_KERNEL
);
49 bitmap
= kzalloc(bitmap_size
, GFP_KERNEL
);
56 mem
->phys_base
= phys_base
;
70 EXPORT_SYMBOL_GPL(pci_epc_mem_init
);
73 * pci_epc_mem_exit() - cleanup the pci_epc_mem structure
74 * @epc: the EPC device that invoked pci_epc_mem_exit
76 * Invoke to cleanup the pci_epc_mem structure allocated in
79 void pci_epc_mem_exit(struct pci_epc
*epc
)
81 struct pci_epc_mem
*mem
= epc
->mem
;
87 EXPORT_SYMBOL_GPL(pci_epc_mem_exit
);
90 * pci_epc_mem_alloc_addr() - allocate memory address from EPC addr space
91 * @epc: the EPC device on which memory has to be allocated
92 * @phys_addr: populate the allocated physical address here
93 * @size: the size of the address space that has to be allocated
95 * Invoke to allocate memory address from the EPC address space. This
96 * is usually done to map the remote RC address into the local system.
98 void __iomem
*pci_epc_mem_alloc_addr(struct pci_epc
*epc
,
99 phys_addr_t
*phys_addr
, size_t size
)
102 void __iomem
*virt_addr
;
103 struct pci_epc_mem
*mem
= epc
->mem
;
104 int order
= get_order(size
);
106 pageno
= bitmap_find_free_region(mem
->bitmap
, mem
->pages
, order
);
110 *phys_addr
= mem
->phys_base
+ (pageno
<< PAGE_SHIFT
);
111 virt_addr
= ioremap(*phys_addr
, size
);
113 bitmap_release_region(mem
->bitmap
, pageno
, order
);
117 EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr
);
120 * pci_epc_mem_free_addr() - free the allocated memory address
121 * @epc: the EPC device on which memory was allocated
122 * @phys_addr: the allocated physical address
123 * @virt_addr: virtual address of the allocated mem space
124 * @size: the size of the allocated address space
126 * Invoke to free the memory allocated using pci_epc_mem_alloc_addr.
128 void pci_epc_mem_free_addr(struct pci_epc
*epc
, phys_addr_t phys_addr
,
129 void __iomem
*virt_addr
, size_t size
)
132 int order
= get_order(size
);
133 struct pci_epc_mem
*mem
= epc
->mem
;
136 pageno
= (phys_addr
- mem
->phys_base
) >> PAGE_SHIFT
;
137 bitmap_release_region(mem
->bitmap
, pageno
, order
);
139 EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr
);
141 MODULE_DESCRIPTION("PCI EPC Address Space Management");
142 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
143 MODULE_LICENSE("GPL v2");