hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/pci/endpoint/pci-epc-mem.c
....@@ -1,5 +1,5 @@
11 // SPDX-License-Identifier: GPL-2.0
2
-/**
2
+/*
33 * PCI Endpoint *Controller* Address Space Management
44 *
55 * Copyright (C) 2017 Texas Instruments
....@@ -23,7 +23,7 @@
2323 static int pci_epc_mem_get_order(struct pci_epc_mem *mem, size_t size)
2424 {
2525 int order;
26
- unsigned int page_shift = ilog2(mem->page_size);
26
+ unsigned int page_shift = ilog2(mem->window.page_size);
2727
2828 size--;
2929 size >>= page_shift;
....@@ -36,62 +36,97 @@
3636 }
3737
3838 /**
39
- * __pci_epc_mem_init() - initialize the pci_epc_mem structure
39
+ * pci_epc_multi_mem_init() - initialize the pci_epc_mem structure
4040 * @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
41
+ * @windows: pointer to windows supported by the device
42
+ * @num_windows: number of windows device supports
4443 *
4544 * Invoke to initialize the pci_epc_mem structure used by the
4645 * endpoint functions to allocate mapped PCI address.
4746 */
48
-int __pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size,
49
- size_t page_size)
47
+int pci_epc_multi_mem_init(struct pci_epc *epc,
48
+ struct pci_epc_mem_window *windows,
49
+ unsigned int num_windows)
5050 {
51
- int ret;
52
- struct pci_epc_mem *mem;
53
- unsigned long *bitmap;
51
+ struct pci_epc_mem *mem = NULL;
52
+ unsigned long *bitmap = NULL;
5453 unsigned int page_shift;
55
- int pages;
54
+ size_t page_size;
5655 int bitmap_size;
56
+ int pages;
57
+ int ret;
58
+ int i;
5759
58
- if (page_size < PAGE_SIZE)
59
- page_size = PAGE_SIZE;
60
+ epc->num_windows = 0;
6061
61
- page_shift = ilog2(page_size);
62
- pages = size >> page_shift;
63
- bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
62
+ if (!windows || !num_windows)
63
+ return -EINVAL;
6464
65
- mem = kzalloc(sizeof(*mem), GFP_KERNEL);
66
- if (!mem) {
67
- ret = -ENOMEM;
68
- goto err;
65
+ epc->windows = kcalloc(num_windows, sizeof(*epc->windows), GFP_KERNEL);
66
+ if (!epc->windows)
67
+ return -ENOMEM;
68
+
69
+ for (i = 0; i < num_windows; i++) {
70
+ page_size = windows[i].page_size;
71
+ if (page_size < PAGE_SIZE)
72
+ page_size = PAGE_SIZE;
73
+ page_shift = ilog2(page_size);
74
+ pages = windows[i].size >> page_shift;
75
+ bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
76
+
77
+ mem = kzalloc(sizeof(*mem), GFP_KERNEL);
78
+ if (!mem) {
79
+ ret = -ENOMEM;
80
+ i--;
81
+ goto err_mem;
82
+ }
83
+
84
+ bitmap = kzalloc(bitmap_size, GFP_KERNEL);
85
+ if (!bitmap) {
86
+ ret = -ENOMEM;
87
+ kfree(mem);
88
+ i--;
89
+ goto err_mem;
90
+ }
91
+
92
+ mem->window.phys_base = windows[i].phys_base;
93
+ mem->window.size = windows[i].size;
94
+ mem->window.page_size = page_size;
95
+ mem->bitmap = bitmap;
96
+ mem->pages = pages;
97
+ mutex_init(&mem->lock);
98
+ epc->windows[i] = mem;
6999 }
70100
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;
101
+ epc->mem = epc->windows[0];
102
+ epc->num_windows = num_windows;
85103
86104 return 0;
87105
88106 err_mem:
89
- kfree(mem);
107
+ for (; i >= 0; i--) {
108
+ mem = epc->windows[i];
109
+ kfree(mem->bitmap);
110
+ kfree(mem);
111
+ }
112
+ kfree(epc->windows);
90113
91
-err:
92
-return ret;
114
+ return ret;
93115 }
94
-EXPORT_SYMBOL_GPL(__pci_epc_mem_init);
116
+EXPORT_SYMBOL_GPL(pci_epc_multi_mem_init);
117
+
118
+int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t base,
119
+ size_t size, size_t page_size)
120
+{
121
+ struct pci_epc_mem_window mem_window;
122
+
123
+ mem_window.phys_base = base;
124
+ mem_window.size = size;
125
+ mem_window.page_size = page_size;
126
+
127
+ return pci_epc_multi_mem_init(epc, &mem_window, 1);
128
+}
129
+EXPORT_SYMBOL_GPL(pci_epc_mem_init);
95130
96131 /**
97132 * pci_epc_mem_exit() - cleanup the pci_epc_mem structure
....@@ -102,11 +137,22 @@
102137 */
103138 void pci_epc_mem_exit(struct pci_epc *epc)
104139 {
105
- struct pci_epc_mem *mem = epc->mem;
140
+ struct pci_epc_mem *mem;
141
+ int i;
106142
143
+ if (!epc->num_windows)
144
+ return;
145
+
146
+ for (i = 0; i < epc->num_windows; i++) {
147
+ mem = epc->windows[i];
148
+ kfree(mem->bitmap);
149
+ kfree(mem);
150
+ }
151
+ kfree(epc->windows);
152
+
153
+ epc->windows = NULL;
107154 epc->mem = NULL;
108
- kfree(mem->bitmap);
109
- kfree(mem);
155
+ epc->num_windows = 0;
110156 }
111157 EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
112158
....@@ -122,30 +168,59 @@
122168 void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
123169 phys_addr_t *phys_addr, size_t size)
124170 {
125
- int pageno;
126171 void __iomem *virt_addr = NULL;
127
- struct pci_epc_mem *mem = epc->mem;
128
- unsigned int page_shift = ilog2(mem->page_size);
172
+ struct pci_epc_mem *mem;
173
+ unsigned int page_shift;
174
+ size_t align_size;
175
+ int pageno;
129176 int order;
177
+ int i;
130178
131
- size = ALIGN(size, mem->page_size);
132
- order = pci_epc_mem_get_order(mem, size);
179
+ for (i = 0; i < epc->num_windows; i++) {
180
+ mem = epc->windows[i];
181
+ mutex_lock(&mem->lock);
182
+ align_size = ALIGN(size, mem->window.page_size);
183
+ order = pci_epc_mem_get_order(mem, align_size);
133184
134
- mutex_lock(&mem->lock);
135
- pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
136
- if (pageno < 0)
137
- goto ret;
185
+ pageno = bitmap_find_free_region(mem->bitmap, mem->pages,
186
+ order);
187
+ if (pageno >= 0) {
188
+ page_shift = ilog2(mem->window.page_size);
189
+ *phys_addr = mem->window.phys_base +
190
+ ((phys_addr_t)pageno << page_shift);
191
+ virt_addr = ioremap(*phys_addr, align_size);
192
+ if (!virt_addr) {
193
+ bitmap_release_region(mem->bitmap,
194
+ pageno, order);
195
+ mutex_unlock(&mem->lock);
196
+ continue;
197
+ }
198
+ mutex_unlock(&mem->lock);
199
+ return virt_addr;
200
+ }
201
+ mutex_unlock(&mem->lock);
202
+ }
138203
139
- *phys_addr = mem->phys_base + (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);
146204 return virt_addr;
147205 }
148206 EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
207
+
208
+static struct pci_epc_mem *pci_epc_get_matching_window(struct pci_epc *epc,
209
+ phys_addr_t phys_addr)
210
+{
211
+ struct pci_epc_mem *mem;
212
+ int i;
213
+
214
+ for (i = 0; i < epc->num_windows; i++) {
215
+ mem = epc->windows[i];
216
+
217
+ if (phys_addr >= mem->window.phys_base &&
218
+ phys_addr < (mem->window.phys_base + mem->window.size))
219
+ return mem;
220
+ }
221
+
222
+ return NULL;
223
+}
149224
150225 /**
151226 * pci_epc_mem_free_addr() - free the allocated memory address
....@@ -159,14 +234,23 @@
159234 void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
160235 void __iomem *virt_addr, size_t size)
161236 {
237
+ struct pci_epc_mem *mem;
238
+ unsigned int page_shift;
239
+ size_t page_size;
162240 int pageno;
163
- struct pci_epc_mem *mem = epc->mem;
164
- unsigned int page_shift = ilog2(mem->page_size);
165241 int order;
166242
243
+ mem = pci_epc_get_matching_window(epc, phys_addr);
244
+ if (!mem) {
245
+ pr_err("failed to get matching window\n");
246
+ return;
247
+ }
248
+
249
+ page_size = mem->window.page_size;
250
+ page_shift = ilog2(page_size);
167251 iounmap(virt_addr);
168
- pageno = (phys_addr - mem->phys_base) >> page_shift;
169
- size = ALIGN(size, mem->page_size);
252
+ pageno = (phys_addr - mem->window.phys_base) >> page_shift;
253
+ size = ALIGN(size, page_size);
170254 order = pci_epc_mem_get_order(mem, size);
171255 mutex_lock(&mem->lock);
172256 bitmap_release_region(mem->bitmap, pageno, order);