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