linux/drivers/pci/endpoint/pci-epf-core.c
<<
>>
Prefs
   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
  18static DEFINE_MUTEX(pci_epf_mutex);
  19
  20static struct bus_type pci_epf_bus_type;
  21static const struct device_type pci_epf_type;
  22
  23/**
  24 * pci_epf_type_add_cfs() - Help function drivers to expose function specific
  25 *                          attributes in configfs
  26 * @epf: the EPF device that has to be configured using configfs
  27 * @group: the parent configfs group (corresponding to entries in
  28 *         pci_epf_device_id)
  29 *
  30 * Invoke to expose function specific attributes in configfs. If the function
  31 * driver does not have anything to expose (attributes configured by user),
  32 * return NULL.
  33 */
  34struct config_group *pci_epf_type_add_cfs(struct pci_epf *epf,
  35                                          struct config_group *group)
  36{
  37        struct config_group *epf_type_group;
  38
  39        if (!epf->driver) {
  40                dev_err(&epf->dev, "epf device not bound to driver\n");
  41                return NULL;
  42        }
  43
  44        if (!epf->driver->ops->add_cfs)
  45                return NULL;
  46
  47        mutex_lock(&epf->lock);
  48        epf_type_group = epf->driver->ops->add_cfs(epf, group);
  49        mutex_unlock(&epf->lock);
  50
  51        return epf_type_group;
  52}
  53EXPORT_SYMBOL_GPL(pci_epf_type_add_cfs);
  54
  55/**
  56 * pci_epf_unbind() - Notify the function driver that the binding between the
  57 *                    EPF device and EPC device has been lost
  58 * @epf: the EPF device which has lost the binding with the EPC device
  59 *
  60 * Invoke to notify the function driver that the binding between the EPF device
  61 * and EPC device has been lost.
  62 */
  63void pci_epf_unbind(struct pci_epf *epf)
  64{
  65        if (!epf->driver) {
  66                dev_WARN(&epf->dev, "epf device not bound to driver\n");
  67                return;
  68        }
  69
  70        mutex_lock(&epf->lock);
  71        epf->driver->ops->unbind(epf);
  72        mutex_unlock(&epf->lock);
  73        module_put(epf->driver->owner);
  74}
  75EXPORT_SYMBOL_GPL(pci_epf_unbind);
  76
  77/**
  78 * pci_epf_bind() - Notify the function driver that the EPF device has been
  79 *                  bound to a EPC device
  80 * @epf: the EPF device which has been bound to the EPC device
  81 *
  82 * Invoke to notify the function driver that it has been bound to a EPC device
  83 */
  84int pci_epf_bind(struct pci_epf *epf)
  85{
  86        int ret;
  87
  88        if (!epf->driver) {
  89                dev_WARN(&epf->dev, "epf device not bound to driver\n");
  90                return -EINVAL;
  91        }
  92
  93        if (!try_module_get(epf->driver->owner))
  94                return -EAGAIN;
  95
  96        mutex_lock(&epf->lock);
  97        ret = epf->driver->ops->bind(epf);
  98        mutex_unlock(&epf->lock);
  99
 100        return ret;
 101}
 102EXPORT_SYMBOL_GPL(pci_epf_bind);
 103
 104/**
 105 * pci_epf_free_space() - free the allocated PCI EPF register space
 106 * @epf: the EPF device from whom to free the memory
 107 * @addr: the virtual address of the PCI EPF register space
 108 * @bar: the BAR number corresponding to the register space
 109 * @type: Identifies if the allocated space is for primary EPC or secondary EPC
 110 *
 111 * Invoke to free the allocated PCI EPF register space.
 112 */
 113void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar,
 114                        enum pci_epc_interface_type type)
 115{
 116        struct device *dev;
 117        struct pci_epf_bar *epf_bar;
 118        struct pci_epc *epc;
 119
 120        if (!addr)
 121                return;
 122
 123        if (type == PRIMARY_INTERFACE) {
 124                epc = epf->epc;
 125                epf_bar = epf->bar;
 126        } else {
 127                epc = epf->sec_epc;
 128                epf_bar = epf->sec_epc_bar;
 129        }
 130
 131        dev = epc->dev.parent;
 132        dma_free_coherent(dev, epf_bar[bar].size, addr,
 133                          epf_bar[bar].phys_addr);
 134
 135        epf_bar[bar].phys_addr = 0;
 136        epf_bar[bar].addr = NULL;
 137        epf_bar[bar].size = 0;
 138        epf_bar[bar].barno = 0;
 139        epf_bar[bar].flags = 0;
 140}
 141EXPORT_SYMBOL_GPL(pci_epf_free_space);
 142
 143/**
 144 * pci_epf_alloc_space() - allocate memory for the PCI EPF register space
 145 * @epf: the EPF device to whom allocate the memory
 146 * @size: the size of the memory that has to be allocated
 147 * @bar: the BAR number corresponding to the allocated register space
 148 * @align: alignment size for the allocation region
 149 * @type: Identifies if the allocation is for primary EPC or secondary EPC
 150 *
 151 * Invoke to allocate memory for the PCI EPF register space.
 152 */
 153void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
 154                          size_t align, enum pci_epc_interface_type type)
 155{
 156        struct pci_epf_bar *epf_bar;
 157        dma_addr_t phys_addr;
 158        struct pci_epc *epc;
 159        struct device *dev;
 160        void *space;
 161
 162        if (size < 128)
 163                size = 128;
 164
 165        if (align)
 166                size = ALIGN(size, align);
 167        else
 168                size = roundup_pow_of_two(size);
 169
 170        if (type == PRIMARY_INTERFACE) {
 171                epc = epf->epc;
 172                epf_bar = epf->bar;
 173        } else {
 174                epc = epf->sec_epc;
 175                epf_bar = epf->sec_epc_bar;
 176        }
 177
 178        dev = epc->dev.parent;
 179        space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL);
 180        if (!space) {
 181                dev_err(dev, "failed to allocate mem space\n");
 182                return NULL;
 183        }
 184
 185        epf_bar[bar].phys_addr = phys_addr;
 186        epf_bar[bar].addr = space;
 187        epf_bar[bar].size = size;
 188        epf_bar[bar].barno = bar;
 189        epf_bar[bar].flags |= upper_32_bits(size) ?
 190                                PCI_BASE_ADDRESS_MEM_TYPE_64 :
 191                                PCI_BASE_ADDRESS_MEM_TYPE_32;
 192
 193        return space;
 194}
 195EXPORT_SYMBOL_GPL(pci_epf_alloc_space);
 196
 197static void pci_epf_remove_cfs(struct pci_epf_driver *driver)
 198{
 199        struct config_group *group, *tmp;
 200
 201        if (!IS_ENABLED(CONFIG_PCI_ENDPOINT_CONFIGFS))
 202                return;
 203
 204        mutex_lock(&pci_epf_mutex);
 205        list_for_each_entry_safe(group, tmp, &driver->epf_group, group_entry)
 206                pci_ep_cfs_remove_epf_group(group);
 207        list_del(&driver->epf_group);
 208        mutex_unlock(&pci_epf_mutex);
 209}
 210
 211/**
 212 * pci_epf_unregister_driver() - unregister the PCI EPF driver
 213 * @driver: the PCI EPF driver that has to be unregistered
 214 *
 215 * Invoke to unregister the PCI EPF driver.
 216 */
 217void pci_epf_unregister_driver(struct pci_epf_driver *driver)
 218{
 219        pci_epf_remove_cfs(driver);
 220        driver_unregister(&driver->driver);
 221}
 222EXPORT_SYMBOL_GPL(pci_epf_unregister_driver);
 223
 224static int pci_epf_add_cfs(struct pci_epf_driver *driver)
 225{
 226        struct config_group *group;
 227        const struct pci_epf_device_id *id;
 228
 229        if (!IS_ENABLED(CONFIG_PCI_ENDPOINT_CONFIGFS))
 230                return 0;
 231
 232        INIT_LIST_HEAD(&driver->epf_group);
 233
 234        id = driver->id_table;
 235        while (id->name[0]) {
 236                group = pci_ep_cfs_add_epf_group(id->name);
 237                if (IS_ERR(group)) {
 238                        pci_epf_remove_cfs(driver);
 239                        return PTR_ERR(group);
 240                }
 241
 242                mutex_lock(&pci_epf_mutex);
 243                list_add_tail(&group->group_entry, &driver->epf_group);
 244                mutex_unlock(&pci_epf_mutex);
 245                id++;
 246        }
 247
 248        return 0;
 249}
 250
 251/**
 252 * __pci_epf_register_driver() - register a new PCI EPF driver
 253 * @driver: structure representing PCI EPF driver
 254 * @owner: the owner of the module that registers the PCI EPF driver
 255 *
 256 * Invoke to register a new PCI EPF driver.
 257 */
 258int __pci_epf_register_driver(struct pci_epf_driver *driver,
 259                              struct module *owner)
 260{
 261        int ret;
 262
 263        if (!driver->ops)
 264                return -EINVAL;
 265
 266        if (!driver->ops->bind || !driver->ops->unbind)
 267                return -EINVAL;
 268
 269        driver->driver.bus = &pci_epf_bus_type;
 270        driver->driver.owner = owner;
 271
 272        ret = driver_register(&driver->driver);
 273        if (ret)
 274                return ret;
 275
 276        pci_epf_add_cfs(driver);
 277
 278        return 0;
 279}
 280EXPORT_SYMBOL_GPL(__pci_epf_register_driver);
 281
 282/**
 283 * pci_epf_destroy() - destroy the created PCI EPF device
 284 * @epf: the PCI EPF device that has to be destroyed.
 285 *
 286 * Invoke to destroy the PCI EPF device created by invoking pci_epf_create().
 287 */
 288void pci_epf_destroy(struct pci_epf *epf)
 289{
 290        device_unregister(&epf->dev);
 291}
 292EXPORT_SYMBOL_GPL(pci_epf_destroy);
 293
 294/**
 295 * pci_epf_create() - create a new PCI EPF device
 296 * @name: the name of the PCI EPF device. This name will be used to bind the
 297 *        the EPF device to a EPF driver
 298 *
 299 * Invoke to create a new PCI EPF device by providing the name of the function
 300 * device.
 301 */
 302struct pci_epf *pci_epf_create(const char *name)
 303{
 304        int ret;
 305        struct pci_epf *epf;
 306        struct device *dev;
 307        int len;
 308
 309        epf = kzalloc(sizeof(*epf), GFP_KERNEL);
 310        if (!epf)
 311                return ERR_PTR(-ENOMEM);
 312
 313        len = strchrnul(name, '.') - name;
 314        epf->name = kstrndup(name, len, GFP_KERNEL);
 315        if (!epf->name) {
 316                kfree(epf);
 317                return ERR_PTR(-ENOMEM);
 318        }
 319
 320        dev = &epf->dev;
 321        device_initialize(dev);
 322        dev->bus = &pci_epf_bus_type;
 323        dev->type = &pci_epf_type;
 324        mutex_init(&epf->lock);
 325
 326        ret = dev_set_name(dev, "%s", name);
 327        if (ret) {
 328                put_device(dev);
 329                return ERR_PTR(ret);
 330        }
 331
 332        ret = device_add(dev);
 333        if (ret) {
 334                put_device(dev);
 335                return ERR_PTR(ret);
 336        }
 337
 338        return epf;
 339}
 340EXPORT_SYMBOL_GPL(pci_epf_create);
 341
 342static void pci_epf_dev_release(struct device *dev)
 343{
 344        struct pci_epf *epf = to_pci_epf(dev);
 345
 346        kfree(epf->name);
 347        kfree(epf);
 348}
 349
 350static const struct device_type pci_epf_type = {
 351        .release        = pci_epf_dev_release,
 352};
 353
 354static int
 355pci_epf_match_id(const struct pci_epf_device_id *id, const struct pci_epf *epf)
 356{
 357        while (id->name[0]) {
 358                if (strcmp(epf->name, id->name) == 0)
 359                        return true;
 360                id++;
 361        }
 362
 363        return false;
 364}
 365
 366static int pci_epf_device_match(struct device *dev, struct device_driver *drv)
 367{
 368        struct pci_epf *epf = to_pci_epf(dev);
 369        struct pci_epf_driver *driver = to_pci_epf_driver(drv);
 370
 371        if (driver->id_table)
 372                return pci_epf_match_id(driver->id_table, epf);
 373
 374        return !strcmp(epf->name, drv->name);
 375}
 376
 377static int pci_epf_device_probe(struct device *dev)
 378{
 379        struct pci_epf *epf = to_pci_epf(dev);
 380        struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver);
 381
 382        if (!driver->probe)
 383                return -ENODEV;
 384
 385        epf->driver = driver;
 386
 387        return driver->probe(epf);
 388}
 389
 390static int pci_epf_device_remove(struct device *dev)
 391{
 392        int ret = 0;
 393        struct pci_epf *epf = to_pci_epf(dev);
 394        struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver);
 395
 396        if (driver->remove)
 397                ret = driver->remove(epf);
 398        epf->driver = NULL;
 399
 400        return ret;
 401}
 402
 403static struct bus_type pci_epf_bus_type = {
 404        .name           = "pci-epf",
 405        .match          = pci_epf_device_match,
 406        .probe          = pci_epf_device_probe,
 407        .remove         = pci_epf_device_remove,
 408};
 409
 410static int __init pci_epf_init(void)
 411{
 412        int ret;
 413
 414        ret = bus_register(&pci_epf_bus_type);
 415        if (ret) {
 416                pr_err("failed to register pci epf bus --> %d\n", ret);
 417                return ret;
 418        }
 419
 420        return 0;
 421}
 422module_init(pci_epf_init);
 423
 424static void __exit pci_epf_exit(void)
 425{
 426        bus_unregister(&pci_epf_bus_type);
 427}
 428module_exit(pci_epf_exit);
 429
 430MODULE_DESCRIPTION("PCI EPF Library");
 431MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
 432MODULE_LICENSE("GPL v2");
 433