1 // SPDX-License-Identifier: GPL-2.0
3 * PCI Endpoint *Function* (EPF) library
5 * Copyright (C) 2017 Texas Instruments
6 * Author: Kishon Vijay Abraham I <kishon@ti.com>
9 #include <linux/device.h>
10 #include <linux/dma-mapping.h>
11 #include <linux/slab.h>
12 #include <linux/module.h>
14 #include <linux/pci-epc.h>
15 #include <linux/pci-epf.h>
16 #include <linux/pci-ep-cfs.h>
18 static struct bus_type pci_epf_bus_type
;
19 static const struct device_type pci_epf_type
;
22 * pci_epf_linkup() - Notify the function driver that EPC device has
23 * established a connection with the Root Complex.
24 * @epf: the EPF device bound to the EPC device which has established
25 * the connection with the host
27 * Invoke to notify the function driver that EPC device has established
28 * a connection with the Root Complex.
30 void pci_epf_linkup(struct pci_epf
*epf
)
33 dev_WARN(&epf
->dev
, "epf device not bound to driver\n");
37 epf
->driver
->ops
->linkup(epf
);
39 EXPORT_SYMBOL_GPL(pci_epf_linkup
);
42 * pci_epf_unbind() - Notify the function driver that the binding between the
43 * EPF device and EPC device has been lost
44 * @epf: the EPF device which has lost the binding with the EPC device
46 * Invoke to notify the function driver that the binding between the EPF device
47 * and EPC device has been lost.
49 void pci_epf_unbind(struct pci_epf
*epf
)
52 dev_WARN(&epf
->dev
, "epf device not bound to driver\n");
56 epf
->driver
->ops
->unbind(epf
);
57 module_put(epf
->driver
->owner
);
59 EXPORT_SYMBOL_GPL(pci_epf_unbind
);
62 * pci_epf_bind() - Notify the function driver that the EPF device has been
63 * bound to a EPC device
64 * @epf: the EPF device which has been bound to the EPC device
66 * Invoke to notify the function driver that it has been bound to a EPC device
68 int pci_epf_bind(struct pci_epf
*epf
)
71 dev_WARN(&epf
->dev
, "epf device not bound to driver\n");
75 if (!try_module_get(epf
->driver
->owner
))
78 return epf
->driver
->ops
->bind(epf
);
80 EXPORT_SYMBOL_GPL(pci_epf_bind
);
83 * pci_epf_free_space() - free the allocated PCI EPF register space
84 * @addr: the virtual address of the PCI EPF register space
85 * @bar: the BAR number corresponding to the register space
87 * Invoke to free the allocated PCI EPF register space.
89 void pci_epf_free_space(struct pci_epf
*epf
, void *addr
, enum pci_barno bar
)
91 struct device
*dev
= epf
->epc
->dev
.parent
;
96 dma_free_coherent(dev
, epf
->bar
[bar
].size
, addr
,
97 epf
->bar
[bar
].phys_addr
);
99 epf
->bar
[bar
].phys_addr
= 0;
100 epf
->bar
[bar
].size
= 0;
102 EXPORT_SYMBOL_GPL(pci_epf_free_space
);
105 * pci_epf_alloc_space() - allocate memory for the PCI EPF register space
106 * @size: the size of the memory that has to be allocated
107 * @bar: the BAR number corresponding to the allocated register space
109 * Invoke to allocate memory for the PCI EPF register space.
111 void *pci_epf_alloc_space(struct pci_epf
*epf
, size_t size
, enum pci_barno bar
)
114 struct device
*dev
= epf
->epc
->dev
.parent
;
115 dma_addr_t phys_addr
;
119 size
= roundup_pow_of_two(size
);
121 space
= dma_alloc_coherent(dev
, size
, &phys_addr
, GFP_KERNEL
);
123 dev_err(dev
, "failed to allocate mem space\n");
127 epf
->bar
[bar
].phys_addr
= phys_addr
;
128 epf
->bar
[bar
].size
= size
;
132 EXPORT_SYMBOL_GPL(pci_epf_alloc_space
);
135 * pci_epf_unregister_driver() - unregister the PCI EPF driver
136 * @driver: the PCI EPF driver that has to be unregistered
138 * Invoke to unregister the PCI EPF driver.
140 void pci_epf_unregister_driver(struct pci_epf_driver
*driver
)
142 pci_ep_cfs_remove_epf_group(driver
->group
);
143 driver_unregister(&driver
->driver
);
145 EXPORT_SYMBOL_GPL(pci_epf_unregister_driver
);
148 * __pci_epf_register_driver() - register a new PCI EPF driver
149 * @driver: structure representing PCI EPF driver
150 * @owner: the owner of the module that registers the PCI EPF driver
152 * Invoke to register a new PCI EPF driver.
154 int __pci_epf_register_driver(struct pci_epf_driver
*driver
,
155 struct module
*owner
)
162 if (!driver
->ops
->bind
|| !driver
->ops
->unbind
|| !driver
->ops
->linkup
)
165 driver
->driver
.bus
= &pci_epf_bus_type
;
166 driver
->driver
.owner
= owner
;
168 ret
= driver_register(&driver
->driver
);
172 driver
->group
= pci_ep_cfs_add_epf_group(driver
->driver
.name
);
176 EXPORT_SYMBOL_GPL(__pci_epf_register_driver
);
179 * pci_epf_destroy() - destroy the created PCI EPF device
180 * @epf: the PCI EPF device that has to be destroyed.
182 * Invoke to destroy the PCI EPF device created by invoking pci_epf_create().
184 void pci_epf_destroy(struct pci_epf
*epf
)
186 device_unregister(&epf
->dev
);
188 EXPORT_SYMBOL_GPL(pci_epf_destroy
);
191 * pci_epf_create() - create a new PCI EPF device
192 * @name: the name of the PCI EPF device. This name will be used to bind the
193 * the EPF device to a EPF driver
195 * Invoke to create a new PCI EPF device by providing the name of the function
198 struct pci_epf
*pci_epf_create(const char *name
)
206 epf
= kzalloc(sizeof(*epf
), GFP_KERNEL
);
212 buf
= kstrdup(name
, GFP_KERNEL
);
219 buf
= strchrnul(buf
, '.');
222 epf
->name
= kstrdup(func_name
, GFP_KERNEL
);
229 device_initialize(dev
);
230 dev
->bus
= &pci_epf_bus_type
;
231 dev
->type
= &pci_epf_type
;
233 ret
= dev_set_name(dev
, "%s", name
);
237 ret
= device_add(dev
);
257 EXPORT_SYMBOL_GPL(pci_epf_create
);
259 const struct pci_epf_device_id
*
260 pci_epf_match_device(const struct pci_epf_device_id
*id
, struct pci_epf
*epf
)
266 if (strcmp(epf
->name
, id
->name
) == 0)
273 EXPORT_SYMBOL_GPL(pci_epf_match_device
);
275 static void pci_epf_dev_release(struct device
*dev
)
277 struct pci_epf
*epf
= to_pci_epf(dev
);
283 static const struct device_type pci_epf_type
= {
284 .release
= pci_epf_dev_release
,
288 pci_epf_match_id(const struct pci_epf_device_id
*id
, const struct pci_epf
*epf
)
290 while (id
->name
[0]) {
291 if (strcmp(epf
->name
, id
->name
) == 0)
299 static int pci_epf_device_match(struct device
*dev
, struct device_driver
*drv
)
301 struct pci_epf
*epf
= to_pci_epf(dev
);
302 struct pci_epf_driver
*driver
= to_pci_epf_driver(drv
);
304 if (driver
->id_table
)
305 return pci_epf_match_id(driver
->id_table
, epf
);
307 return !strcmp(epf
->name
, drv
->name
);
310 static int pci_epf_device_probe(struct device
*dev
)
312 struct pci_epf
*epf
= to_pci_epf(dev
);
313 struct pci_epf_driver
*driver
= to_pci_epf_driver(dev
->driver
);
318 epf
->driver
= driver
;
320 return driver
->probe(epf
);
323 static int pci_epf_device_remove(struct device
*dev
)
326 struct pci_epf
*epf
= to_pci_epf(dev
);
327 struct pci_epf_driver
*driver
= to_pci_epf_driver(dev
->driver
);
330 ret
= driver
->remove(epf
);
336 static struct bus_type pci_epf_bus_type
= {
338 .match
= pci_epf_device_match
,
339 .probe
= pci_epf_device_probe
,
340 .remove
= pci_epf_device_remove
,
343 static int __init
pci_epf_init(void)
347 ret
= bus_register(&pci_epf_bus_type
);
349 pr_err("failed to register pci epf bus --> %d\n", ret
);
355 module_init(pci_epf_init
);
357 static void __exit
pci_epf_exit(void)
359 bus_unregister(&pci_epf_bus_type
);
361 module_exit(pci_epf_exit
);
363 MODULE_DESCRIPTION("PCI EPF Library");
364 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
365 MODULE_LICENSE("GPL v2");