linux/drivers/fpga/fpga-bridge.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * FPGA Bridge Framework Driver
   4 *
   5 *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
   6 *  Copyright (C) 2017 Intel Corporation
   7 */
   8#include <linux/fpga/fpga-bridge.h>
   9#include <linux/idr.h>
  10#include <linux/kernel.h>
  11#include <linux/module.h>
  12#include <linux/of_platform.h>
  13#include <linux/slab.h>
  14#include <linux/spinlock.h>
  15
  16static DEFINE_IDA(fpga_bridge_ida);
  17static struct class *fpga_bridge_class;
  18
  19/* Lock for adding/removing bridges to linked lists*/
  20static DEFINE_SPINLOCK(bridge_list_lock);
  21
  22/**
  23 * fpga_bridge_enable - Enable transactions on the bridge
  24 *
  25 * @bridge: FPGA bridge
  26 *
  27 * Return: 0 for success, error code otherwise.
  28 */
  29int fpga_bridge_enable(struct fpga_bridge *bridge)
  30{
  31        dev_dbg(&bridge->dev, "enable\n");
  32
  33        if (bridge->br_ops && bridge->br_ops->enable_set)
  34                return bridge->br_ops->enable_set(bridge, 1);
  35
  36        return 0;
  37}
  38EXPORT_SYMBOL_GPL(fpga_bridge_enable);
  39
  40/**
  41 * fpga_bridge_disable - Disable transactions on the bridge
  42 *
  43 * @bridge: FPGA bridge
  44 *
  45 * Return: 0 for success, error code otherwise.
  46 */
  47int fpga_bridge_disable(struct fpga_bridge *bridge)
  48{
  49        dev_dbg(&bridge->dev, "disable\n");
  50
  51        if (bridge->br_ops && bridge->br_ops->enable_set)
  52                return bridge->br_ops->enable_set(bridge, 0);
  53
  54        return 0;
  55}
  56EXPORT_SYMBOL_GPL(fpga_bridge_disable);
  57
  58static struct fpga_bridge *__fpga_bridge_get(struct device *dev,
  59                                             struct fpga_image_info *info)
  60{
  61        struct fpga_bridge *bridge;
  62        int ret = -ENODEV;
  63
  64        bridge = to_fpga_bridge(dev);
  65
  66        bridge->info = info;
  67
  68        if (!mutex_trylock(&bridge->mutex)) {
  69                ret = -EBUSY;
  70                goto err_dev;
  71        }
  72
  73        if (!try_module_get(dev->parent->driver->owner))
  74                goto err_ll_mod;
  75
  76        dev_dbg(&bridge->dev, "get\n");
  77
  78        return bridge;
  79
  80err_ll_mod:
  81        mutex_unlock(&bridge->mutex);
  82err_dev:
  83        put_device(dev);
  84        return ERR_PTR(ret);
  85}
  86
  87/**
  88 * of_fpga_bridge_get - get an exclusive reference to an fpga bridge
  89 *
  90 * @np: node pointer of an FPGA bridge
  91 * @info: fpga image specific information
  92 *
  93 * Return fpga_bridge struct if successful.
  94 * Return -EBUSY if someone already has a reference to the bridge.
  95 * Return -ENODEV if @np is not an FPGA Bridge.
  96 */
  97struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
  98                                       struct fpga_image_info *info)
  99{
 100        struct device *dev;
 101
 102        dev = class_find_device_by_of_node(fpga_bridge_class, np);
 103        if (!dev)
 104                return ERR_PTR(-ENODEV);
 105
 106        return __fpga_bridge_get(dev, info);
 107}
 108EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
 109
 110static int fpga_bridge_dev_match(struct device *dev, const void *data)
 111{
 112        return dev->parent == data;
 113}
 114
 115/**
 116 * fpga_bridge_get - get an exclusive reference to an fpga bridge
 117 * @dev:        parent device that fpga bridge was registered with
 118 * @info:       fpga manager info
 119 *
 120 * Given a device, get an exclusive reference to an fpga bridge.
 121 *
 122 * Return: fpga bridge struct or IS_ERR() condition containing error code.
 123 */
 124struct fpga_bridge *fpga_bridge_get(struct device *dev,
 125                                    struct fpga_image_info *info)
 126{
 127        struct device *bridge_dev;
 128
 129        bridge_dev = class_find_device(fpga_bridge_class, NULL, dev,
 130                                       fpga_bridge_dev_match);
 131        if (!bridge_dev)
 132                return ERR_PTR(-ENODEV);
 133
 134        return __fpga_bridge_get(bridge_dev, info);
 135}
 136EXPORT_SYMBOL_GPL(fpga_bridge_get);
 137
 138/**
 139 * fpga_bridge_put - release a reference to a bridge
 140 *
 141 * @bridge: FPGA bridge
 142 */
 143void fpga_bridge_put(struct fpga_bridge *bridge)
 144{
 145        dev_dbg(&bridge->dev, "put\n");
 146
 147        bridge->info = NULL;
 148        module_put(bridge->dev.parent->driver->owner);
 149        mutex_unlock(&bridge->mutex);
 150        put_device(&bridge->dev);
 151}
 152EXPORT_SYMBOL_GPL(fpga_bridge_put);
 153
 154/**
 155 * fpga_bridges_enable - enable bridges in a list
 156 * @bridge_list: list of FPGA bridges
 157 *
 158 * Enable each bridge in the list.  If list is empty, do nothing.
 159 *
 160 * Return 0 for success or empty bridge list; return error code otherwise.
 161 */
 162int fpga_bridges_enable(struct list_head *bridge_list)
 163{
 164        struct fpga_bridge *bridge;
 165        int ret;
 166
 167        list_for_each_entry(bridge, bridge_list, node) {
 168                ret = fpga_bridge_enable(bridge);
 169                if (ret)
 170                        return ret;
 171        }
 172
 173        return 0;
 174}
 175EXPORT_SYMBOL_GPL(fpga_bridges_enable);
 176
 177/**
 178 * fpga_bridges_disable - disable bridges in a list
 179 *
 180 * @bridge_list: list of FPGA bridges
 181 *
 182 * Disable each bridge in the list.  If list is empty, do nothing.
 183 *
 184 * Return 0 for success or empty bridge list; return error code otherwise.
 185 */
 186int fpga_bridges_disable(struct list_head *bridge_list)
 187{
 188        struct fpga_bridge *bridge;
 189        int ret;
 190
 191        list_for_each_entry(bridge, bridge_list, node) {
 192                ret = fpga_bridge_disable(bridge);
 193                if (ret)
 194                        return ret;
 195        }
 196
 197        return 0;
 198}
 199EXPORT_SYMBOL_GPL(fpga_bridges_disable);
 200
 201/**
 202 * fpga_bridges_put - put bridges
 203 *
 204 * @bridge_list: list of FPGA bridges
 205 *
 206 * For each bridge in the list, put the bridge and remove it from the list.
 207 * If list is empty, do nothing.
 208 */
 209void fpga_bridges_put(struct list_head *bridge_list)
 210{
 211        struct fpga_bridge *bridge, *next;
 212        unsigned long flags;
 213
 214        list_for_each_entry_safe(bridge, next, bridge_list, node) {
 215                fpga_bridge_put(bridge);
 216
 217                spin_lock_irqsave(&bridge_list_lock, flags);
 218                list_del(&bridge->node);
 219                spin_unlock_irqrestore(&bridge_list_lock, flags);
 220        }
 221}
 222EXPORT_SYMBOL_GPL(fpga_bridges_put);
 223
 224/**
 225 * of_fpga_bridge_get_to_list - get a bridge, add it to a list
 226 *
 227 * @np: node pointer of an FPGA bridge
 228 * @info: fpga image specific information
 229 * @bridge_list: list of FPGA bridges
 230 *
 231 * Get an exclusive reference to the bridge and it to the list.
 232 *
 233 * Return 0 for success, error code from of_fpga_bridge_get() otherwise.
 234 */
 235int of_fpga_bridge_get_to_list(struct device_node *np,
 236                               struct fpga_image_info *info,
 237                               struct list_head *bridge_list)
 238{
 239        struct fpga_bridge *bridge;
 240        unsigned long flags;
 241
 242        bridge = of_fpga_bridge_get(np, info);
 243        if (IS_ERR(bridge))
 244                return PTR_ERR(bridge);
 245
 246        spin_lock_irqsave(&bridge_list_lock, flags);
 247        list_add(&bridge->node, bridge_list);
 248        spin_unlock_irqrestore(&bridge_list_lock, flags);
 249
 250        return 0;
 251}
 252EXPORT_SYMBOL_GPL(of_fpga_bridge_get_to_list);
 253
 254/**
 255 * fpga_bridge_get_to_list - given device, get a bridge, add it to a list
 256 *
 257 * @dev: FPGA bridge device
 258 * @info: fpga image specific information
 259 * @bridge_list: list of FPGA bridges
 260 *
 261 * Get an exclusive reference to the bridge and it to the list.
 262 *
 263 * Return 0 for success, error code from fpga_bridge_get() otherwise.
 264 */
 265int fpga_bridge_get_to_list(struct device *dev,
 266                            struct fpga_image_info *info,
 267                            struct list_head *bridge_list)
 268{
 269        struct fpga_bridge *bridge;
 270        unsigned long flags;
 271
 272        bridge = fpga_bridge_get(dev, info);
 273        if (IS_ERR(bridge))
 274                return PTR_ERR(bridge);
 275
 276        spin_lock_irqsave(&bridge_list_lock, flags);
 277        list_add(&bridge->node, bridge_list);
 278        spin_unlock_irqrestore(&bridge_list_lock, flags);
 279
 280        return 0;
 281}
 282EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list);
 283
 284static ssize_t name_show(struct device *dev,
 285                         struct device_attribute *attr, char *buf)
 286{
 287        struct fpga_bridge *bridge = to_fpga_bridge(dev);
 288
 289        return sprintf(buf, "%s\n", bridge->name);
 290}
 291
 292static ssize_t state_show(struct device *dev,
 293                          struct device_attribute *attr, char *buf)
 294{
 295        struct fpga_bridge *bridge = to_fpga_bridge(dev);
 296        int enable = 1;
 297
 298        if (bridge->br_ops && bridge->br_ops->enable_show)
 299                enable = bridge->br_ops->enable_show(bridge);
 300
 301        return sprintf(buf, "%s\n", enable ? "enabled" : "disabled");
 302}
 303
 304static DEVICE_ATTR_RO(name);
 305static DEVICE_ATTR_RO(state);
 306
 307static struct attribute *fpga_bridge_attrs[] = {
 308        &dev_attr_name.attr,
 309        &dev_attr_state.attr,
 310        NULL,
 311};
 312ATTRIBUTE_GROUPS(fpga_bridge);
 313
 314/**
 315 * fpga_bridge_create - create and initialize a struct fpga_bridge
 316 * @parent:     FPGA bridge device from pdev
 317 * @name:       FPGA bridge name
 318 * @br_ops:     pointer to structure of fpga bridge ops
 319 * @priv:       FPGA bridge private data
 320 *
 321 * The caller of this function is responsible for freeing the bridge with
 322 * fpga_bridge_free().  Using devm_fpga_bridge_create() instead is recommended.
 323 *
 324 * Return: struct fpga_bridge or NULL
 325 */
 326struct fpga_bridge *fpga_bridge_create(struct device *parent, const char *name,
 327                                       const struct fpga_bridge_ops *br_ops,
 328                                       void *priv)
 329{
 330        struct fpga_bridge *bridge;
 331        int id, ret;
 332
 333        if (!name || !strlen(name)) {
 334                dev_err(parent, "Attempt to register with no name!\n");
 335                return NULL;
 336        }
 337
 338        bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
 339        if (!bridge)
 340                return NULL;
 341
 342        id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL);
 343        if (id < 0)
 344                goto error_kfree;
 345
 346        mutex_init(&bridge->mutex);
 347        INIT_LIST_HEAD(&bridge->node);
 348
 349        bridge->name = name;
 350        bridge->br_ops = br_ops;
 351        bridge->priv = priv;
 352
 353        device_initialize(&bridge->dev);
 354        bridge->dev.groups = br_ops->groups;
 355        bridge->dev.class = fpga_bridge_class;
 356        bridge->dev.parent = parent;
 357        bridge->dev.of_node = parent->of_node;
 358        bridge->dev.id = id;
 359
 360        ret = dev_set_name(&bridge->dev, "br%d", id);
 361        if (ret)
 362                goto error_device;
 363
 364        return bridge;
 365
 366error_device:
 367        ida_simple_remove(&fpga_bridge_ida, id);
 368error_kfree:
 369        kfree(bridge);
 370
 371        return NULL;
 372}
 373EXPORT_SYMBOL_GPL(fpga_bridge_create);
 374
 375/**
 376 * fpga_bridge_free - free an fpga bridge created by fpga_bridge_create()
 377 * @bridge:     FPGA bridge struct
 378 */
 379void fpga_bridge_free(struct fpga_bridge *bridge)
 380{
 381        ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
 382        kfree(bridge);
 383}
 384EXPORT_SYMBOL_GPL(fpga_bridge_free);
 385
 386static void devm_fpga_bridge_release(struct device *dev, void *res)
 387{
 388        struct fpga_bridge *bridge = *(struct fpga_bridge **)res;
 389
 390        fpga_bridge_free(bridge);
 391}
 392
 393/**
 394 * devm_fpga_bridge_create - create and init a managed struct fpga_bridge
 395 * @parent:     FPGA bridge device from pdev
 396 * @name:       FPGA bridge name
 397 * @br_ops:     pointer to structure of fpga bridge ops
 398 * @priv:       FPGA bridge private data
 399 *
 400 * This function is intended for use in an FPGA bridge driver's probe function.
 401 * After the bridge driver creates the struct with devm_fpga_bridge_create(), it
 402 * should register the bridge with fpga_bridge_register().  The bridge driver's
 403 * remove function should call fpga_bridge_unregister().  The bridge struct
 404 * allocated with this function will be freed automatically on driver detach.
 405 * This includes the case of a probe function returning error before calling
 406 * fpga_bridge_register(), the struct will still get cleaned up.
 407 *
 408 *  Return: struct fpga_bridge or NULL
 409 */
 410struct fpga_bridge
 411*devm_fpga_bridge_create(struct device *parent, const char *name,
 412                         const struct fpga_bridge_ops *br_ops, void *priv)
 413{
 414        struct fpga_bridge **ptr, *bridge;
 415
 416        ptr = devres_alloc(devm_fpga_bridge_release, sizeof(*ptr), GFP_KERNEL);
 417        if (!ptr)
 418                return NULL;
 419
 420        bridge = fpga_bridge_create(parent, name, br_ops, priv);
 421        if (!bridge) {
 422                devres_free(ptr);
 423        } else {
 424                *ptr = bridge;
 425                devres_add(parent, ptr);
 426        }
 427
 428        return bridge;
 429}
 430EXPORT_SYMBOL_GPL(devm_fpga_bridge_create);
 431
 432/**
 433 * fpga_bridge_register - register an FPGA bridge
 434 *
 435 * @bridge: FPGA bridge struct
 436 *
 437 * Return: 0 for success, error code otherwise.
 438 */
 439int fpga_bridge_register(struct fpga_bridge *bridge)
 440{
 441        struct device *dev = &bridge->dev;
 442        int ret;
 443
 444        ret = device_add(dev);
 445        if (ret)
 446                return ret;
 447
 448        of_platform_populate(dev->of_node, NULL, NULL, dev);
 449
 450        dev_info(dev->parent, "fpga bridge [%s] registered\n", bridge->name);
 451
 452        return 0;
 453}
 454EXPORT_SYMBOL_GPL(fpga_bridge_register);
 455
 456/**
 457 * fpga_bridge_unregister - unregister an FPGA bridge
 458 *
 459 * @bridge: FPGA bridge struct
 460 *
 461 * This function is intended for use in an FPGA bridge driver's remove function.
 462 */
 463void fpga_bridge_unregister(struct fpga_bridge *bridge)
 464{
 465        /*
 466         * If the low level driver provides a method for putting bridge into
 467         * a desired state upon unregister, do it.
 468         */
 469        if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove)
 470                bridge->br_ops->fpga_bridge_remove(bridge);
 471
 472        device_unregister(&bridge->dev);
 473}
 474EXPORT_SYMBOL_GPL(fpga_bridge_unregister);
 475
 476static void fpga_bridge_dev_release(struct device *dev)
 477{
 478}
 479
 480static int __init fpga_bridge_dev_init(void)
 481{
 482        fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge");
 483        if (IS_ERR(fpga_bridge_class))
 484                return PTR_ERR(fpga_bridge_class);
 485
 486        fpga_bridge_class->dev_groups = fpga_bridge_groups;
 487        fpga_bridge_class->dev_release = fpga_bridge_dev_release;
 488
 489        return 0;
 490}
 491
 492static void __exit fpga_bridge_dev_exit(void)
 493{
 494        class_destroy(fpga_bridge_class);
 495        ida_destroy(&fpga_bridge_ida);
 496}
 497
 498MODULE_DESCRIPTION("FPGA Bridge Driver");
 499MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
 500MODULE_LICENSE("GPL v2");
 501
 502subsys_initcall(fpga_bridge_dev_init);
 503module_exit(fpga_bridge_dev_exit);
 504