summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2017-04-10 09:55:10 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-04-11 15:18:35 -0400
commit5e8cb4033807e39849b753e5399ec130c0995f1f (patch)
treec2d924acfd79187ad4066f075998c3b21890d109 /drivers
parentd4c7d1a089d6fddf38c4fcdc91f15791bfb59a95 (diff)
PCI: endpoint: Add EP core layer to enable EP controller and EP functions
Introduce a new EP core layer in order to support endpoint functions in linux kernel. This comprises the EPC library (Endpoint Controller Library) and EPF library (Endpoint Function Library). EPC library implements functions specific to an endpoint controller and EPF library implements functions specific to an endpoint function. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Acked-by: Joao Pinto <jpinto@synopsys.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/pci/Kconfig1
-rw-r--r--drivers/pci/endpoint/Kconfig20
-rw-r--r--drivers/pci/endpoint/Makefile6
-rw-r--r--drivers/pci/endpoint/pci-epc-core.c576
-rw-r--r--drivers/pci/endpoint/pci-epc-mem.c143
-rw-r--r--drivers/pci/endpoint/pci-epf-core.c355
7 files changed, 1103 insertions, 0 deletions
diff --git a/drivers/Makefile b/drivers/Makefile
index 2eced9afba53..a5f8e43b2c4d 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -14,7 +14,9 @@ obj-$(CONFIG_GENERIC_PHY) += phy/
14obj-$(CONFIG_PINCTRL) += pinctrl/ 14obj-$(CONFIG_PINCTRL) += pinctrl/
15obj-$(CONFIG_GPIOLIB) += gpio/ 15obj-$(CONFIG_GPIOLIB) += gpio/
16obj-y += pwm/ 16obj-y += pwm/
17
17obj-$(CONFIG_PCI) += pci/ 18obj-$(CONFIG_PCI) += pci/
19obj-$(CONFIG_PCI_ENDPOINT) += pci/endpoint/
18# PCI dwc controller drivers 20# PCI dwc controller drivers
19obj-y += pci/dwc/ 21obj-y += pci/dwc/
20 22
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index df141420c902..9747c1ec8c74 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -134,3 +134,4 @@ config PCI_HYPERV
134source "drivers/pci/hotplug/Kconfig" 134source "drivers/pci/hotplug/Kconfig"
135source "drivers/pci/dwc/Kconfig" 135source "drivers/pci/dwc/Kconfig"
136source "drivers/pci/host/Kconfig" 136source "drivers/pci/host/Kconfig"
137source "drivers/pci/endpoint/Kconfig"
diff --git a/drivers/pci/endpoint/Kconfig b/drivers/pci/endpoint/Kconfig
new file mode 100644
index 000000000000..a5442ace7077
--- /dev/null
+++ b/drivers/pci/endpoint/Kconfig
@@ -0,0 +1,20 @@
1#
2# PCI Endpoint Support
3#
4
5menu "PCI Endpoint"
6
7config PCI_ENDPOINT
8 bool "PCI Endpoint Support"
9 help
10 Enable this configuration option to support configurable PCI
11 endpoint. This should be enabled if the platform has a PCI
12 controller that can operate in endpoint mode.
13
14 Enabling this option will build the endpoint library, which
15 includes endpoint controller library and endpoint function
16 library.
17
18 If in doubt, say "N" to disable Endpoint support.
19
20endmenu
diff --git a/drivers/pci/endpoint/Makefile b/drivers/pci/endpoint/Makefile
new file mode 100644
index 000000000000..dc1bc16491e6
--- /dev/null
+++ b/drivers/pci/endpoint/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for PCI Endpoint Support
3#
4
5obj-$(CONFIG_PCI_ENDPOINT) += pci-epc-core.o pci-epf-core.o\
6 pci-epc-mem.o
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
new file mode 100644
index 000000000000..7c71dd94721c
--- /dev/null
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -0,0 +1,576 @@
1/**
2 * PCI Endpoint *Controller* (EPC) library
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
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.
10 *
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.
15 *
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/>.
18 */
19
20#include <linux/device.h>
21#include <linux/dma-mapping.h>
22#include <linux/slab.h>
23#include <linux/module.h>
24
25#include <linux/pci-epc.h>
26#include <linux/pci-epf.h>
27
28static struct class *pci_epc_class;
29
30static void devm_pci_epc_release(struct device *dev, void *res)
31{
32 struct pci_epc *epc = *(struct pci_epc **)res;
33
34 pci_epc_destroy(epc);
35}
36
37static int devm_pci_epc_match(struct device *dev, void *res, void *match_data)
38{
39 struct pci_epc **epc = res;
40
41 return *epc == match_data;
42}
43
44/**
45 * pci_epc_put() - release the PCI endpoint controller
46 * @epc: epc returned by pci_epc_get()
47 *
48 * release the refcount the caller obtained by invoking pci_epc_get()
49 */
50void pci_epc_put(struct pci_epc *epc)
51{
52 if (!epc || IS_ERR(epc))
53 return;
54
55 module_put(epc->ops->owner);
56 put_device(&epc->dev);
57}
58EXPORT_SYMBOL_GPL(pci_epc_put);
59
60/**
61 * pci_epc_get() - get the PCI endpoint controller
62 * @epc_name: device name of the endpoint controller
63 *
64 * Invoke to get struct pci_epc * corresponding to the device name of the
65 * endpoint controller
66 */
67struct pci_epc *pci_epc_get(const char *epc_name)
68{
69 int ret = -EINVAL;
70 struct pci_epc *epc;
71 struct device *dev;
72 struct class_dev_iter iter;
73
74 class_dev_iter_init(&iter, pci_epc_class, NULL, NULL);
75 while ((dev = class_dev_iter_next(&iter))) {
76 if (strcmp(epc_name, dev_name(dev)))
77 continue;
78
79 epc = to_pci_epc(dev);
80 if (!try_module_get(epc->ops->owner)) {
81 ret = -EINVAL;
82 goto err;
83 }
84
85 class_dev_iter_exit(&iter);
86 get_device(&epc->dev);
87 return epc;
88 }
89
90err:
91 class_dev_iter_exit(&iter);
92 return ERR_PTR(ret);
93}
94EXPORT_SYMBOL_GPL(pci_epc_get);
95
96/**
97 * pci_epc_stop() - stop the PCI link
98 * @epc: the link of the EPC device that has to be stopped
99 *
100 * Invoke to stop the PCI link
101 */
102void pci_epc_stop(struct pci_epc *epc)
103{
104 unsigned long flags;
105
106 if (IS_ERR(epc) || !epc->ops->stop)
107 return;
108
109 spin_lock_irqsave(&epc->lock, flags);
110 epc->ops->stop(epc);
111 spin_unlock_irqrestore(&epc->lock, flags);
112}
113EXPORT_SYMBOL_GPL(pci_epc_stop);
114
115/**
116 * pci_epc_start() - start the PCI link
117 * @epc: the link of *this* EPC device has to be started
118 *
119 * Invoke to start the PCI link
120 */
121int pci_epc_start(struct pci_epc *epc)
122{
123 int ret;
124 unsigned long flags;
125
126 if (IS_ERR(epc))
127 return -EINVAL;
128
129 if (!epc->ops->start)
130 return 0;
131
132 spin_lock_irqsave(&epc->lock, flags);
133 ret = epc->ops->start(epc);
134 spin_unlock_irqrestore(&epc->lock, flags);
135
136 return ret;
137}
138EXPORT_SYMBOL_GPL(pci_epc_start);
139
140/**
141 * pci_epc_raise_irq() - interrupt the host system
142 * @epc: the EPC device which has to interrupt the host
143 * @type: specify the type of interrupt; legacy or MSI
144 * @interrupt_num: the MSI interrupt number
145 *
146 * Invoke to raise an MSI or legacy interrupt
147 */
148int pci_epc_raise_irq(struct pci_epc *epc, enum pci_epc_irq_type type,
149 u8 interrupt_num)
150{
151 int ret;
152 unsigned long flags;
153
154 if (IS_ERR(epc))
155 return -EINVAL;
156
157 if (!epc->ops->raise_irq)
158 return 0;
159
160 spin_lock_irqsave(&epc->lock, flags);
161 ret = epc->ops->raise_irq(epc, type, interrupt_num);
162 spin_unlock_irqrestore(&epc->lock, flags);
163
164 return ret;
165}
166EXPORT_SYMBOL_GPL(pci_epc_raise_irq);
167
168/**
169 * pci_epc_get_msi() - get the number of MSI interrupt numbers allocated
170 * @epc: the EPC device to which MSI interrupts was requested
171 *
172 * Invoke to get the number of MSI interrupts allocated by the RC
173 */
174int pci_epc_get_msi(struct pci_epc *epc)
175{
176 int interrupt;
177 unsigned long flags;
178
179 if (IS_ERR(epc))
180 return 0;
181
182 if (!epc->ops->get_msi)
183 return 0;
184
185 spin_lock_irqsave(&epc->lock, flags);
186 interrupt = epc->ops->get_msi(epc);
187 spin_unlock_irqrestore(&epc->lock, flags);
188
189 if (interrupt < 0)
190 return 0;
191
192 interrupt = 1 << interrupt;
193
194 return interrupt;
195}
196EXPORT_SYMBOL_GPL(pci_epc_get_msi);
197
198/**
199 * pci_epc_set_msi() - set the number of MSI interrupt numbers required
200 * @epc: the EPC device on which MSI has to be configured
201 * @interrupts: number of MSI interrupts required by the EPF
202 *
203 * Invoke to set the required number of MSI interrupts.
204 */
205int pci_epc_set_msi(struct pci_epc *epc, u8 interrupts)
206{
207 int ret;
208 u8 encode_int;
209 unsigned long flags;
210
211 if (IS_ERR(epc))
212 return -EINVAL;
213
214 if (!epc->ops->set_msi)
215 return 0;
216
217 encode_int = order_base_2(interrupts);
218
219 spin_lock_irqsave(&epc->lock, flags);
220 ret = epc->ops->set_msi(epc, encode_int);
221 spin_unlock_irqrestore(&epc->lock, flags);
222
223 return ret;
224}
225EXPORT_SYMBOL_GPL(pci_epc_set_msi);
226
227/**
228 * pci_epc_unmap_addr() - unmap CPU address from PCI address
229 * @epc: the EPC device on which address is allocated
230 * @phys_addr: physical address of the local system
231 *
232 * Invoke to unmap the CPU address from PCI address.
233 */
234void pci_epc_unmap_addr(struct pci_epc *epc, phys_addr_t phys_addr)
235{
236 unsigned long flags;
237
238 if (IS_ERR(epc))
239 return;
240
241 if (!epc->ops->unmap_addr)
242 return;
243
244 spin_lock_irqsave(&epc->lock, flags);
245 epc->ops->unmap_addr(epc, phys_addr);
246 spin_unlock_irqrestore(&epc->lock, flags);
247}
248EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
249
250/**
251 * pci_epc_map_addr() - map CPU address to PCI address
252 * @epc: the EPC device on which address is allocated
253 * @phys_addr: physical address of the local system
254 * @pci_addr: PCI address to which the physical address should be mapped
255 * @size: the size of the allocation
256 *
257 * Invoke to map CPU address with PCI address.
258 */
259int pci_epc_map_addr(struct pci_epc *epc, phys_addr_t phys_addr,
260 u64 pci_addr, size_t size)
261{
262 int ret;
263 unsigned long flags;
264
265 if (IS_ERR(epc))
266 return -EINVAL;
267
268 if (!epc->ops->map_addr)
269 return 0;
270
271 spin_lock_irqsave(&epc->lock, flags);
272 ret = epc->ops->map_addr(epc, phys_addr, pci_addr, size);
273 spin_unlock_irqrestore(&epc->lock, flags);
274
275 return ret;
276}
277EXPORT_SYMBOL_GPL(pci_epc_map_addr);
278
279/**
280 * pci_epc_clear_bar() - reset the BAR
281 * @epc: the EPC device for which the BAR has to be cleared
282 * @bar: the BAR number that has to be reset
283 *
284 * Invoke to reset the BAR of the endpoint device.
285 */
286void pci_epc_clear_bar(struct pci_epc *epc, int bar)
287{
288 unsigned long flags;
289
290 if (IS_ERR(epc))
291 return;
292
293 if (!epc->ops->clear_bar)
294 return;
295
296 spin_lock_irqsave(&epc->lock, flags);
297 epc->ops->clear_bar(epc, bar);
298 spin_unlock_irqrestore(&epc->lock, flags);
299}
300EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
301
302/**
303 * pci_epc_set_bar() - configure BAR in order for host to assign PCI addr space
304 * @epc: the EPC device on which BAR has to be configured
305 * @bar: the BAR number that has to be configured
306 * @size: the size of the addr space
307 * @flags: specify memory allocation/io allocation/32bit address/64 bit address
308 *
309 * Invoke to configure the BAR of the endpoint device.
310 */
311int pci_epc_set_bar(struct pci_epc *epc, enum pci_barno bar,
312 dma_addr_t bar_phys, size_t size, int flags)
313{
314 int ret;
315 unsigned long irq_flags;
316
317 if (IS_ERR(epc))
318 return -EINVAL;
319
320 if (!epc->ops->set_bar)
321 return 0;
322
323 spin_lock_irqsave(&epc->lock, irq_flags);
324 ret = epc->ops->set_bar(epc, bar, bar_phys, size, flags);
325 spin_unlock_irqrestore(&epc->lock, irq_flags);
326
327 return ret;
328}
329EXPORT_SYMBOL_GPL(pci_epc_set_bar);
330
331/**
332 * pci_epc_write_header() - write standard configuration header
333 * @epc: the EPC device to which the configuration header should be written
334 * @header: standard configuration header fields
335 *
336 * Invoke to write the configuration header to the endpoint controller. Every
337 * endpoint controller will have a dedicated location to which the standard
338 * configuration header would be written. The callback function should write
339 * the header fields to this dedicated location.
340 */
341int pci_epc_write_header(struct pci_epc *epc, struct pci_epf_header *header)
342{
343 int ret;
344 unsigned long flags;
345
346 if (IS_ERR(epc))
347 return -EINVAL;
348
349 if (!epc->ops->write_header)
350 return 0;
351
352 spin_lock_irqsave(&epc->lock, flags);
353 ret = epc->ops->write_header(epc, header);
354 spin_unlock_irqrestore(&epc->lock, flags);
355
356 return ret;
357}
358EXPORT_SYMBOL_GPL(pci_epc_write_header);
359
360/**
361 * pci_epc_add_epf() - bind PCI endpoint function to an endpoint controller
362 * @epc: the EPC device to which the endpoint function should be added
363 * @epf: the endpoint function to be added
364 *
365 * A PCI endpoint device can have one or more functions. In the case of PCIe,
366 * the specification allows up to 8 PCIe endpoint functions. Invoke
367 * pci_epc_add_epf() to add a PCI endpoint function to an endpoint controller.
368 */
369int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
370{
371 unsigned long flags;
372
373 if (epf->epc)
374 return -EBUSY;
375
376 if (IS_ERR(epc))
377 return -EINVAL;
378
379 if (epf->func_no > epc->max_functions - 1)
380 return -EINVAL;
381
382 epf->epc = epc;
383 dma_set_coherent_mask(&epf->dev, epc->dev.coherent_dma_mask);
384 epf->dev.dma_mask = epc->dev.dma_mask;
385
386 spin_lock_irqsave(&epc->lock, flags);
387 list_add_tail(&epf->list, &epc->pci_epf);
388 spin_unlock_irqrestore(&epc->lock, flags);
389
390 return 0;
391}
392EXPORT_SYMBOL_GPL(pci_epc_add_epf);
393
394/**
395 * pci_epc_remove_epf() - remove PCI endpoint function from endpoint controller
396 * @epc: the EPC device from which the endpoint function should be removed
397 * @epf: the endpoint function to be removed
398 *
399 * Invoke to remove PCI endpoint function from the endpoint controller.
400 */
401void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf)
402{
403 unsigned long flags;
404
405 if (!epc || IS_ERR(epc))
406 return;
407
408 spin_lock_irqsave(&epc->lock, flags);
409 list_del(&epf->list);
410 spin_unlock_irqrestore(&epc->lock, flags);
411}
412EXPORT_SYMBOL_GPL(pci_epc_remove_epf);
413
414/**
415 * pci_epc_linkup() - Notify the EPF device that EPC device has established a
416 * connection with the Root Complex.
417 * @epc: the EPC device which has established link with the host
418 *
419 * Invoke to Notify the EPF device that the EPC device has established a
420 * connection with the Root Complex.
421 */
422void pci_epc_linkup(struct pci_epc *epc)
423{
424 unsigned long flags;
425 struct pci_epf *epf;
426
427 if (!epc || IS_ERR(epc))
428 return;
429
430 spin_lock_irqsave(&epc->lock, flags);
431 list_for_each_entry(epf, &epc->pci_epf, list)
432 pci_epf_linkup(epf);
433 spin_unlock_irqrestore(&epc->lock, flags);
434}
435EXPORT_SYMBOL_GPL(pci_epc_linkup);
436
437/**
438 * pci_epc_destroy() - destroy the EPC device
439 * @epc: the EPC device that has to be destroyed
440 *
441 * Invoke to destroy the PCI EPC device
442 */
443void pci_epc_destroy(struct pci_epc *epc)
444{
445 device_unregister(&epc->dev);
446 kfree(epc);
447}
448EXPORT_SYMBOL_GPL(pci_epc_destroy);
449
450/**
451 * devm_pci_epc_destroy() - destroy the EPC device
452 * @dev: device that wants to destroy the EPC
453 * @epc: the EPC device that has to be destroyed
454 *
455 * Invoke to destroy the devres associated with this
456 * pci_epc and destroy the EPC device.
457 */
458void devm_pci_epc_destroy(struct device *dev, struct pci_epc *epc)
459{
460 int r;
461
462 r = devres_destroy(dev, devm_pci_epc_release, devm_pci_epc_match,
463 epc);
464 dev_WARN_ONCE(dev, r, "couldn't find PCI EPC resource\n");
465}
466EXPORT_SYMBOL_GPL(devm_pci_epc_destroy);
467
468/**
469 * __pci_epc_create() - create a new endpoint controller (EPC) device
470 * @dev: device that is creating the new EPC
471 * @ops: function pointers for performing EPC operations
472 * @owner: the owner of the module that creates the EPC device
473 *
474 * Invoke to create a new EPC device and add it to pci_epc class.
475 */
476struct pci_epc *
477__pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
478 struct module *owner)
479{
480 int ret;
481 struct pci_epc *epc;
482
483 if (WARN_ON(!dev)) {
484 ret = -EINVAL;
485 goto err_ret;
486 }
487
488 epc = kzalloc(sizeof(*epc), GFP_KERNEL);
489 if (!epc) {
490 ret = -ENOMEM;
491 goto err_ret;
492 }
493
494 spin_lock_init(&epc->lock);
495 INIT_LIST_HEAD(&epc->pci_epf);
496
497 device_initialize(&epc->dev);
498 dma_set_coherent_mask(&epc->dev, dev->coherent_dma_mask);
499 epc->dev.class = pci_epc_class;
500 epc->dev.dma_mask = dev->dma_mask;
501 epc->ops = ops;
502
503 ret = dev_set_name(&epc->dev, "%s", dev_name(dev));
504 if (ret)
505 goto put_dev;
506
507 ret = device_add(&epc->dev);
508 if (ret)
509 goto put_dev;
510
511 return epc;
512
513put_dev:
514 put_device(&epc->dev);
515 kfree(epc);
516
517err_ret:
518 return ERR_PTR(ret);
519}
520EXPORT_SYMBOL_GPL(__pci_epc_create);
521
522/**
523 * __devm_pci_epc_create() - create a new endpoint controller (EPC) device
524 * @dev: device that is creating the new EPC
525 * @ops: function pointers for performing EPC operations
526 * @owner: the owner of the module that creates the EPC device
527 *
528 * Invoke to create a new EPC device and add it to pci_epc class.
529 * While at that, it also associates the device with the pci_epc using devres.
530 * On driver detach, release function is invoked on the devres data,
531 * then, devres data is freed.
532 */
533struct pci_epc *
534__devm_pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
535 struct module *owner)
536{
537 struct pci_epc **ptr, *epc;
538
539 ptr = devres_alloc(devm_pci_epc_release, sizeof(*ptr), GFP_KERNEL);
540 if (!ptr)
541 return ERR_PTR(-ENOMEM);
542
543 epc = __pci_epc_create(dev, ops, owner);
544 if (!IS_ERR(epc)) {
545 *ptr = epc;
546 devres_add(dev, ptr);
547 } else {
548 devres_free(ptr);
549 }
550
551 return epc;
552}
553EXPORT_SYMBOL_GPL(__devm_pci_epc_create);
554
555static int __init pci_epc_init(void)
556{
557 pci_epc_class = class_create(THIS_MODULE, "pci_epc");
558 if (IS_ERR(pci_epc_class)) {
559 pr_err("failed to create pci epc class --> %ld\n",
560 PTR_ERR(pci_epc_class));
561 return PTR_ERR(pci_epc_class);
562 }
563
564 return 0;
565}
566module_init(pci_epc_init);
567
568static void __exit pci_epc_exit(void)
569{
570 class_destroy(pci_epc_class);
571}
572module_exit(pci_epc_exit);
573
574MODULE_DESCRIPTION("PCI EPC Library");
575MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
576MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/endpoint/pci-epc-mem.c b/drivers/pci/endpoint/pci-epc-mem.c
new file mode 100644
index 000000000000..3a94cc1caf22
--- /dev/null
+++ b/drivers/pci/endpoint/pci-epc-mem.c
@@ -0,0 +1,143 @@
1/**
2 * PCI Endpoint *Controller* Address Space Management
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
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.
10 *
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.
15 *
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/>.
18 */
19
20#include <linux/io.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23
24#include <linux/pci-epc.h>
25
26/**
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
31 *
32 * Invoke to initialize the pci_epc_mem structure used by the
33 * endpoint functions to allocate mapped PCI address.
34 */
35int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size)
36{
37 int ret;
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);
42
43 mem = kzalloc(sizeof(*mem), GFP_KERNEL);
44 if (!mem) {
45 ret = -ENOMEM;
46 goto err;
47 }
48
49 bitmap = kzalloc(bitmap_size, GFP_KERNEL);
50 if (!bitmap) {
51 ret = -ENOMEM;
52 goto err_mem;
53 }
54
55 mem->bitmap = bitmap;
56 mem->phys_base = phys_base;
57 mem->pages = pages;
58 mem->size = size;
59
60 epc->mem = mem;
61
62 return 0;
63
64err_mem:
65 kfree(mem);
66
67err:
68return ret;
69}
70EXPORT_SYMBOL_GPL(pci_epc_mem_init);
71
72/**
73 * pci_epc_mem_exit() - cleanup the pci_epc_mem structure
74 * @epc: the EPC device that invoked pci_epc_mem_exit
75 *
76 * Invoke to cleanup the pci_epc_mem structure allocated in
77 * pci_epc_mem_init().
78 */
79void pci_epc_mem_exit(struct pci_epc *epc)
80{
81 struct pci_epc_mem *mem = epc->mem;
82
83 epc->mem = NULL;
84 kfree(mem->bitmap);
85 kfree(mem);
86}
87EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
88
89/**
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
94 *
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.
97 */
98void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
99 phys_addr_t *phys_addr, size_t size)
100{
101 int pageno;
102 void __iomem *virt_addr;
103 struct pci_epc_mem *mem = epc->mem;
104 int order = get_order(size);
105
106 pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
107 if (pageno < 0)
108 return NULL;
109
110 *phys_addr = mem->phys_base + (pageno << PAGE_SHIFT);
111 virt_addr = ioremap(*phys_addr, size);
112 if (!virt_addr)
113 bitmap_release_region(mem->bitmap, pageno, order);
114
115 return virt_addr;
116}
117EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
118
119/**
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
125 *
126 * Invoke to free the memory allocated using pci_epc_mem_alloc_addr.
127 */
128void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
129 void __iomem *virt_addr, size_t size)
130{
131 int pageno;
132 int order = get_order(size);
133 struct pci_epc_mem *mem = epc->mem;
134
135 iounmap(virt_addr);
136 pageno = (phys_addr - mem->phys_base) >> PAGE_SHIFT;
137 bitmap_release_region(mem->bitmap, pageno, order);
138}
139EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr);
140
141MODULE_DESCRIPTION("PCI EPC Address Space Management");
142MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
143MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
new file mode 100644
index 000000000000..a281c599a504
--- /dev/null
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -0,0 +1,355 @@
1/**
2 * PCI Endpoint *Function* (EPF) library
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
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.
10 *
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.
15 *
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/>.
18 */
19
20#include <linux/device.h>
21#include <linux/dma-mapping.h>
22#include <linux/slab.h>
23#include <linux/module.h>
24
25#include <linux/pci-epc.h>
26#include <linux/pci-epf.h>
27
28static struct bus_type pci_epf_bus_type;
29static struct device_type pci_epf_type;
30
31/**
32 * pci_epf_linkup() - Notify the function driver that EPC device has
33 * established a connection with the Root Complex.
34 * @epf: the EPF device bound to the EPC device which has established
35 * the connection with the host
36 *
37 * Invoke to notify the function driver that EPC device has established
38 * a connection with the Root Complex.
39 */
40void pci_epf_linkup(struct pci_epf *epf)
41{
42 if (!epf->driver) {
43 dev_WARN(&epf->dev, "epf device not bound to driver\n");
44 return;
45 }
46
47 epf->driver->ops->linkup(epf);
48}
49EXPORT_SYMBOL_GPL(pci_epf_linkup);
50
51/**
52 * pci_epf_unbind() - Notify the function driver that the binding between the
53 * EPF device and EPC device has been lost
54 * @epf: the EPF device which has lost the binding with the EPC device
55 *
56 * Invoke to notify the function driver that the binding between the EPF device
57 * and EPC device has been lost.
58 */
59void pci_epf_unbind(struct pci_epf *epf)
60{
61 if (!epf->driver) {
62 dev_WARN(&epf->dev, "epf device not bound to driver\n");
63 return;
64 }
65
66 epf->driver->ops->unbind(epf);
67 module_put(epf->driver->owner);
68}
69EXPORT_SYMBOL_GPL(pci_epf_unbind);
70
71/**
72 * pci_epf_bind() - Notify the function driver that the EPF device has been
73 * bound to a EPC device
74 * @epf: the EPF device which has been bound to the EPC device
75 *
76 * Invoke to notify the function driver that it has been bound to a EPC device
77 */
78int pci_epf_bind(struct pci_epf *epf)
79{
80 if (!epf->driver) {
81 dev_WARN(&epf->dev, "epf device not bound to driver\n");
82 return -EINVAL;
83 }
84
85 if (!try_module_get(epf->driver->owner))
86 return -EAGAIN;
87
88 return epf->driver->ops->bind(epf);
89}
90EXPORT_SYMBOL_GPL(pci_epf_bind);
91
92/**
93 * pci_epf_free_space() - free the allocated PCI EPF register space
94 * @addr: the virtual address of the PCI EPF register space
95 * @bar: the BAR number corresponding to the register space
96 *
97 * Invoke to free the allocated PCI EPF register space.
98 */
99void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar)
100{
101 struct device *dev = &epf->dev;
102
103 if (!addr)
104 return;
105
106 dma_free_coherent(dev, epf->bar[bar].size, addr,
107 epf->bar[bar].phys_addr);
108
109 epf->bar[bar].phys_addr = 0;
110 epf->bar[bar].size = 0;
111}
112EXPORT_SYMBOL_GPL(pci_epf_free_space);
113
114/**
115 * pci_epf_alloc_space() - allocate memory for the PCI EPF register space
116 * @size: the size of the memory that has to be allocated
117 * @bar: the BAR number corresponding to the allocated register space
118 *
119 * Invoke to allocate memory for the PCI EPF register space.
120 */
121void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar)
122{
123 void *space;
124 struct device *dev = &epf->dev;
125 dma_addr_t phys_addr;
126
127 if (size < 128)
128 size = 128;
129 size = roundup_pow_of_two(size);
130
131 space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL);
132 if (!space) {
133 dev_err(dev, "failed to allocate mem space\n");
134 return NULL;
135 }
136
137 epf->bar[bar].phys_addr = phys_addr;
138 epf->bar[bar].size = size;
139
140 return space;
141}
142EXPORT_SYMBOL_GPL(pci_epf_alloc_space);
143
144/**
145 * pci_epf_unregister_driver() - unregister the PCI EPF driver
146 * @driver: the PCI EPF driver that has to be unregistered
147 *
148 * Invoke to unregister the PCI EPF driver.
149 */
150void pci_epf_unregister_driver(struct pci_epf_driver *driver)
151{
152 driver_unregister(&driver->driver);
153}
154EXPORT_SYMBOL_GPL(pci_epf_unregister_driver);
155
156/**
157 * __pci_epf_register_driver() - register a new PCI EPF driver
158 * @driver: structure representing PCI EPF driver
159 * @owner: the owner of the module that registers the PCI EPF driver
160 *
161 * Invoke to register a new PCI EPF driver.
162 */
163int __pci_epf_register_driver(struct pci_epf_driver *driver,
164 struct module *owner)
165{
166 int ret;
167
168 if (!driver->ops)
169 return -EINVAL;
170
171 if (!driver->ops->bind || !driver->ops->unbind || !driver->ops->linkup)
172 return -EINVAL;
173
174 driver->driver.bus = &pci_epf_bus_type;
175 driver->driver.owner = owner;
176
177 ret = driver_register(&driver->driver);
178 if (ret)
179 return ret;
180
181 return 0;
182}
183EXPORT_SYMBOL_GPL(__pci_epf_register_driver);
184
185/**
186 * pci_epf_destroy() - destroy the created PCI EPF device
187 * @epf: the PCI EPF device that has to be destroyed.
188 *
189 * Invoke to destroy the PCI EPF device created by invoking pci_epf_create().
190 */
191void pci_epf_destroy(struct pci_epf *epf)
192{
193 device_unregister(&epf->dev);
194}
195EXPORT_SYMBOL_GPL(pci_epf_destroy);
196
197/**
198 * pci_epf_create() - create a new PCI EPF device
199 * @name: the name of the PCI EPF device. This name will be used to bind the
200 * the EPF device to a EPF driver
201 *
202 * Invoke to create a new PCI EPF device by providing the name of the function
203 * device.
204 */
205struct pci_epf *pci_epf_create(const char *name)
206{
207 int ret;
208 struct pci_epf *epf;
209 struct device *dev;
210 char *func_name;
211 char *buf;
212
213 epf = kzalloc(sizeof(*epf), GFP_KERNEL);
214 if (!epf) {
215 ret = -ENOMEM;
216 goto err_ret;
217 }
218
219 buf = kstrdup(name, GFP_KERNEL);
220 if (!buf) {
221 ret = -ENOMEM;
222 goto free_epf;
223 }
224
225 func_name = buf;
226 buf = strchrnul(buf, '.');
227 *buf = '\0';
228
229 epf->name = kstrdup(func_name, GFP_KERNEL);
230 if (!epf->name) {
231 ret = -ENOMEM;
232 goto free_func_name;
233 }
234
235 dev = &epf->dev;
236 device_initialize(dev);
237 dev->bus = &pci_epf_bus_type;
238 dev->type = &pci_epf_type;
239
240 ret = dev_set_name(dev, "%s", name);
241 if (ret)
242 goto put_dev;
243
244 ret = device_add(dev);
245 if (ret)
246 goto put_dev;
247
248 kfree(func_name);
249 return epf;
250
251put_dev:
252 put_device(dev);
253 kfree(epf->name);
254
255free_func_name:
256 kfree(func_name);
257
258free_epf:
259 kfree(epf);
260
261err_ret:
262 return ERR_PTR(ret);
263}
264EXPORT_SYMBOL_GPL(pci_epf_create);
265
266static void pci_epf_dev_release(struct device *dev)
267{
268 struct pci_epf *epf = to_pci_epf(dev);
269
270 kfree(epf->name);
271 kfree(epf);
272}
273
274static struct device_type pci_epf_type = {
275 .release = pci_epf_dev_release,
276};
277
278static int
279pci_epf_match_id(const struct pci_epf_device_id *id, const struct pci_epf *epf)
280{
281 while (id->name[0]) {
282 if (strcmp(epf->name, id->name) == 0)
283 return true;
284 id++;
285 }
286
287 return false;
288}
289
290static int pci_epf_device_match(struct device *dev, struct device_driver *drv)
291{
292 struct pci_epf *epf = to_pci_epf(dev);
293 struct pci_epf_driver *driver = to_pci_epf_driver(drv);
294
295 if (driver->id_table)
296 return pci_epf_match_id(driver->id_table, epf);
297
298 return !strcmp(epf->name, drv->name);
299}
300
301static int pci_epf_device_probe(struct device *dev)
302{
303 struct pci_epf *epf = to_pci_epf(dev);
304 struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver);
305
306 if (!driver->probe)
307 return -ENODEV;
308
309 epf->driver = driver;
310
311 return driver->probe(epf);
312}
313
314static int pci_epf_device_remove(struct device *dev)
315{
316 int ret;
317 struct pci_epf *epf = to_pci_epf(dev);
318 struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver);
319
320 ret = driver->remove(epf);
321 epf->driver = NULL;
322
323 return ret;
324}
325
326static struct bus_type pci_epf_bus_type = {
327 .name = "pci-epf",
328 .match = pci_epf_device_match,
329 .probe = pci_epf_device_probe,
330 .remove = pci_epf_device_remove,
331};
332
333static int __init pci_epf_init(void)
334{
335 int ret;
336
337 ret = bus_register(&pci_epf_bus_type);
338 if (ret) {
339 pr_err("failed to register pci epf bus --> %d\n", ret);
340 return ret;
341 }
342
343 return 0;
344}
345module_init(pci_epf_init);
346
347static void __exit pci_epf_exit(void)
348{
349 bus_unregister(&pci_epf_bus_type);
350}
351module_exit(pci_epf_exit);
352
353MODULE_DESCRIPTION("PCI EPF Library");
354MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
355MODULE_LICENSE("GPL v2");