1 // SPDX-License-Identifier: GPL-2.0 2 /** 3 * PCI Endpoint *Function* (EPF) library 4 * 5 * Copyright (C) 2017 Texas Instruments 6 * Author: Kishon Vijay Abraham I <kishon@ti.com> 7 */ 8 9 #include <linux/device.h> 10 #include <linux/dma-mapping.h> 11 #include <linux/slab.h> 12 #include <linux/module.h> 13 14 #include <linux/pci-epc.h> 15 #include <linux/pci-epf.h> 16 #include <linux/pci-ep-cfs.h> 17 18 static struct bus_type pci_epf_bus_type; 19 static const struct device_type pci_epf_type; 20 21 /** 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 26 * 27 * Invoke to notify the function driver that EPC device has established 28 * a connection with the Root Complex. 29 */ 30 void pci_epf_linkup(struct pci_epf *epf) 31 { 32 if (!epf->driver) { 33 dev_WARN(&epf->dev, "epf device not bound to driver\n"); 34 return; 35 } 36 37 epf->driver->ops->linkup(epf); 38 } 39 EXPORT_SYMBOL_GPL(pci_epf_linkup); 40 41 /** 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 45 * 46 * Invoke to notify the function driver that the binding between the EPF device 47 * and EPC device has been lost. 48 */ 49 void pci_epf_unbind(struct pci_epf *epf) 50 { 51 if (!epf->driver) { 52 dev_WARN(&epf->dev, "epf device not bound to driver\n"); 53 return; 54 } 55 56 epf->driver->ops->unbind(epf); 57 module_put(epf->driver->owner); 58 } 59 EXPORT_SYMBOL_GPL(pci_epf_unbind); 60 61 /** 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 65 * 66 * Invoke to notify the function driver that it has been bound to a EPC device 67 */ 68 int pci_epf_bind(struct pci_epf *epf) 69 { 70 if (!epf->driver) { 71 dev_WARN(&epf->dev, "epf device not bound to driver\n"); 72 return -EINVAL; 73 } 74 75 if (!try_module_get(epf->driver->owner)) 76 return -EAGAIN; 77 78 return epf->driver->ops->bind(epf); 79 } 80 EXPORT_SYMBOL_GPL(pci_epf_bind); 81 82 /** 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 86 * 87 * Invoke to free the allocated PCI EPF register space. 88 */ 89 void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar) 90 { 91 struct device *dev = epf->epc->dev.parent; 92 93 if (!addr) 94 return; 95 96 dma_free_coherent(dev, epf->bar[bar].size, addr, 97 epf->bar[bar].phys_addr); 98 99 epf->bar[bar].phys_addr = 0; 100 epf->bar[bar].size = 0; 101 epf->bar[bar].barno = 0; 102 epf->bar[bar].flags = 0; 103 } 104 EXPORT_SYMBOL_GPL(pci_epf_free_space); 105 106 /** 107 * pci_epf_alloc_space() - allocate memory for the PCI EPF register space 108 * @size: the size of the memory that has to be allocated 109 * @bar: the BAR number corresponding to the allocated register space 110 * 111 * Invoke to allocate memory for the PCI EPF register space. 112 */ 113 void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar) 114 { 115 void *space; 116 struct device *dev = epf->epc->dev.parent; 117 dma_addr_t phys_addr; 118 119 if (size < 128) 120 size = 128; 121 size = roundup_pow_of_two(size); 122 123 space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL); 124 if (!space) { 125 dev_err(dev, "failed to allocate mem space\n"); 126 return NULL; 127 } 128 129 epf->bar[bar].phys_addr = phys_addr; 130 epf->bar[bar].size = size; 131 epf->bar[bar].barno = bar; 132 epf->bar[bar].flags = PCI_BASE_ADDRESS_SPACE_MEMORY; 133 134 return space; 135 } 136 EXPORT_SYMBOL_GPL(pci_epf_alloc_space); 137 138 /** 139 * pci_epf_unregister_driver() - unregister the PCI EPF driver 140 * @driver: the PCI EPF driver that has to be unregistered 141 * 142 * Invoke to unregister the PCI EPF driver. 143 */ 144 void pci_epf_unregister_driver(struct pci_epf_driver *driver) 145 { 146 pci_ep_cfs_remove_epf_group(driver->group); 147 driver_unregister(&driver->driver); 148 } 149 EXPORT_SYMBOL_GPL(pci_epf_unregister_driver); 150 151 /** 152 * __pci_epf_register_driver() - register a new PCI EPF driver 153 * @driver: structure representing PCI EPF driver 154 * @owner: the owner of the module that registers the PCI EPF driver 155 * 156 * Invoke to register a new PCI EPF driver. 157 */ 158 int __pci_epf_register_driver(struct pci_epf_driver *driver, 159 struct module *owner) 160 { 161 int ret; 162 163 if (!driver->ops) 164 return -EINVAL; 165 166 if (!driver->ops->bind || !driver->ops->unbind || !driver->ops->linkup) 167 return -EINVAL; 168 169 driver->driver.bus = &pci_epf_bus_type; 170 driver->driver.owner = owner; 171 172 ret = driver_register(&driver->driver); 173 if (ret) 174 return ret; 175 176 driver->group = pci_ep_cfs_add_epf_group(driver->driver.name); 177 178 return 0; 179 } 180 EXPORT_SYMBOL_GPL(__pci_epf_register_driver); 181 182 /** 183 * pci_epf_destroy() - destroy the created PCI EPF device 184 * @epf: the PCI EPF device that has to be destroyed. 185 * 186 * Invoke to destroy the PCI EPF device created by invoking pci_epf_create(). 187 */ 188 void pci_epf_destroy(struct pci_epf *epf) 189 { 190 device_unregister(&epf->dev); 191 } 192 EXPORT_SYMBOL_GPL(pci_epf_destroy); 193 194 /** 195 * pci_epf_create() - create a new PCI EPF device 196 * @name: the name of the PCI EPF device. This name will be used to bind the 197 * the EPF device to a EPF driver 198 * 199 * Invoke to create a new PCI EPF device by providing the name of the function 200 * device. 201 */ 202 struct pci_epf *pci_epf_create(const char *name) 203 { 204 int ret; 205 struct pci_epf *epf; 206 struct device *dev; 207 int len; 208 209 epf = kzalloc(sizeof(*epf), GFP_KERNEL); 210 if (!epf) 211 return ERR_PTR(-ENOMEM); 212 213 len = strchrnul(name, '.') - name; 214 epf->name = kstrndup(name, len, GFP_KERNEL); 215 if (!epf->name) { 216 kfree(epf); 217 return ERR_PTR(-ENOMEM); 218 } 219 220 dev = &epf->dev; 221 device_initialize(dev); 222 dev->bus = &pci_epf_bus_type; 223 dev->type = &pci_epf_type; 224 225 ret = dev_set_name(dev, "%s", name); 226 if (ret) { 227 put_device(dev); 228 return ERR_PTR(ret); 229 } 230 231 ret = device_add(dev); 232 if (ret) { 233 put_device(dev); 234 return ERR_PTR(ret); 235 } 236 237 return epf; 238 } 239 EXPORT_SYMBOL_GPL(pci_epf_create); 240 241 const struct pci_epf_device_id * 242 pci_epf_match_device(const struct pci_epf_device_id *id, struct pci_epf *epf) 243 { 244 if (!id || !epf) 245 return NULL; 246 247 while (*id->name) { 248 if (strcmp(epf->name, id->name) == 0) 249 return id; 250 id++; 251 } 252 253 return NULL; 254 } 255 EXPORT_SYMBOL_GPL(pci_epf_match_device); 256 257 static void pci_epf_dev_release(struct device *dev) 258 { 259 struct pci_epf *epf = to_pci_epf(dev); 260 261 kfree(epf->name); 262 kfree(epf); 263 } 264 265 static const struct device_type pci_epf_type = { 266 .release = pci_epf_dev_release, 267 }; 268 269 static int 270 pci_epf_match_id(const struct pci_epf_device_id *id, const struct pci_epf *epf) 271 { 272 while (id->name[0]) { 273 if (strcmp(epf->name, id->name) == 0) 274 return true; 275 id++; 276 } 277 278 return false; 279 } 280 281 static int pci_epf_device_match(struct device *dev, struct device_driver *drv) 282 { 283 struct pci_epf *epf = to_pci_epf(dev); 284 struct pci_epf_driver *driver = to_pci_epf_driver(drv); 285 286 if (driver->id_table) 287 return pci_epf_match_id(driver->id_table, epf); 288 289 return !strcmp(epf->name, drv->name); 290 } 291 292 static int pci_epf_device_probe(struct device *dev) 293 { 294 struct pci_epf *epf = to_pci_epf(dev); 295 struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver); 296 297 if (!driver->probe) 298 return -ENODEV; 299 300 epf->driver = driver; 301 302 return driver->probe(epf); 303 } 304 305 static int pci_epf_device_remove(struct device *dev) 306 { 307 int ret = 0; 308 struct pci_epf *epf = to_pci_epf(dev); 309 struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver); 310 311 if (driver->remove) 312 ret = driver->remove(epf); 313 epf->driver = NULL; 314 315 return ret; 316 } 317 318 static struct bus_type pci_epf_bus_type = { 319 .name = "pci-epf", 320 .match = pci_epf_device_match, 321 .probe = pci_epf_device_probe, 322 .remove = pci_epf_device_remove, 323 }; 324 325 static int __init pci_epf_init(void) 326 { 327 int ret; 328 329 ret = bus_register(&pci_epf_bus_type); 330 if (ret) { 331 pr_err("failed to register pci epf bus --> %d\n", ret); 332 return ret; 333 } 334 335 return 0; 336 } 337 module_init(pci_epf_init); 338 339 static void __exit pci_epf_exit(void) 340 { 341 bus_unregister(&pci_epf_bus_type); 342 } 343 module_exit(pci_epf_exit); 344 345 MODULE_DESCRIPTION("PCI EPF Library"); 346 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>"); 347 MODULE_LICENSE("GPL v2"); 348