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