linux/drivers/fpga/fpga-bridge.c
<<
>>
Prefs
   1/*
   2 * FPGA Bridge Framework Driver
   3 *
   4 *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 *
  15 * You should have received a copy of the GNU General Public License along with
  16 * this program.  If not, see <http://www.gnu.org/licenses/>.
  17 */
  18#include <linux/fpga/fpga-bridge.h>
  19#include <linux/idr.h>
  20#include <linux/kernel.h>
  21#include <linux/module.h>
  22#include <linux/of_platform.h>
  23#include <linux/slab.h>
  24#include <linux/spinlock.h>
  25
  26/* For enabling manual bridge set(enable/disable) function */
  27#ifdef CONFIG_DEBUG_KERNEL
  28#undef DEBUG
  29#define DEBUG
  30#endif
  31
  32static DEFINE_IDA(fpga_bridge_ida);
  33static struct class *fpga_bridge_class;
  34
  35/* Lock for adding/removing bridges to linked lists*/
  36static spinlock_t bridge_list_lock;
  37
  38static int fpga_bridge_of_node_match(struct device *dev, const void *data)
  39{
  40        return dev->of_node == data;
  41}
  42
  43/**
  44 * fpga_bridge_enable - Enable transactions on the bridge
  45 *
  46 * @bridge: FPGA bridge
  47 *
  48 * Return: 0 for success, error code otherwise.
  49 */
  50int fpga_bridge_enable(struct fpga_bridge *bridge)
  51{
  52        dev_dbg(&bridge->dev, "enable\n");
  53
  54        if (bridge->br_ops && bridge->br_ops->enable_set)
  55                return bridge->br_ops->enable_set(bridge, 1);
  56
  57        return 0;
  58}
  59EXPORT_SYMBOL_GPL(fpga_bridge_enable);
  60
  61/**
  62 * fpga_bridge_disable - Disable transactions on the bridge
  63 *
  64 * @bridge: FPGA bridge
  65 *
  66 * Return: 0 for success, error code otherwise.
  67 */
  68int fpga_bridge_disable(struct fpga_bridge *bridge)
  69{
  70        dev_dbg(&bridge->dev, "disable\n");
  71
  72        if (bridge->br_ops && bridge->br_ops->enable_set)
  73                return bridge->br_ops->enable_set(bridge, 0);
  74
  75        return 0;
  76}
  77EXPORT_SYMBOL_GPL(fpga_bridge_disable);
  78
  79/**
  80 * of_fpga_bridge_get - get an exclusive reference to a fpga bridge
  81 *
  82 * @np: node pointer of a FPGA bridge
  83 * @info: fpga image specific information
  84 *
  85 * Return fpga_bridge struct if successful.
  86 * Return -EBUSY if someone already has a reference to the bridge.
  87 * Return -ENODEV if @np is not a FPGA Bridge.
  88 */
  89struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
  90                                       struct fpga_image_info *info)
  91
  92{
  93        struct device *dev;
  94        struct fpga_bridge *bridge;
  95        int ret = -ENODEV;
  96
  97        dev = class_find_device(fpga_bridge_class, NULL, np,
  98                                fpga_bridge_of_node_match);
  99        if (!dev)
 100                goto err_dev;
 101
 102        bridge = to_fpga_bridge(dev);
 103        if (!bridge)
 104                goto err_dev;
 105
 106        bridge->info = info;
 107
 108        if (!mutex_trylock(&bridge->mutex)) {
 109                ret = -EBUSY;
 110                goto err_dev;
 111        }
 112
 113        if (!try_module_get(dev->parent->driver->owner))
 114                goto err_ll_mod;
 115
 116        dev_dbg(&bridge->dev, "get\n");
 117
 118        return bridge;
 119
 120err_ll_mod:
 121        mutex_unlock(&bridge->mutex);
 122err_dev:
 123        put_device(dev);
 124        return ERR_PTR(ret);
 125}
 126EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
 127
 128/**
 129 * fpga_bridge_put - release a reference to a bridge
 130 *
 131 * @bridge: FPGA bridge
 132 */
 133void fpga_bridge_put(struct fpga_bridge *bridge)
 134{
 135        dev_dbg(&bridge->dev, "put\n");
 136
 137        bridge->info = NULL;
 138        module_put(bridge->dev.parent->driver->owner);
 139        mutex_unlock(&bridge->mutex);
 140        put_device(&bridge->dev);
 141}
 142EXPORT_SYMBOL_GPL(fpga_bridge_put);
 143
 144/**
 145 * fpga_bridges_enable - enable bridges in a list
 146 * @bridge_list: list of FPGA bridges
 147 *
 148 * Enable each bridge in the list.  If list is empty, do nothing.
 149 *
 150 * Return 0 for success or empty bridge list; return error code otherwise.
 151 */
 152int fpga_bridges_enable(struct list_head *bridge_list)
 153{
 154        struct fpga_bridge *bridge;
 155        struct list_head *node;
 156        int ret;
 157
 158        list_for_each(node, bridge_list) {
 159                bridge = list_entry(node, struct fpga_bridge, node);
 160                ret = fpga_bridge_enable(bridge);
 161                if (ret)
 162                        return ret;
 163        }
 164
 165        return 0;
 166}
 167EXPORT_SYMBOL_GPL(fpga_bridges_enable);
 168
 169/**
 170 * fpga_bridges_disable - disable bridges in a list
 171 *
 172 * @bridge_list: list of FPGA bridges
 173 *
 174 * Disable each bridge in the list.  If list is empty, do nothing.
 175 *
 176 * Return 0 for success or empty bridge list; return error code otherwise.
 177 */
 178int fpga_bridges_disable(struct list_head *bridge_list)
 179{
 180        struct fpga_bridge *bridge;
 181        struct list_head *node;
 182        int ret;
 183
 184        list_for_each(node, bridge_list) {
 185                bridge = list_entry(node, struct fpga_bridge, node);
 186                ret = fpga_bridge_disable(bridge);
 187                if (ret)
 188                        return ret;
 189        }
 190
 191        return 0;
 192}
 193EXPORT_SYMBOL_GPL(fpga_bridges_disable);
 194
 195/**
 196 * fpga_bridges_put - put bridges
 197 *
 198 * @bridge_list: list of FPGA bridges
 199 *
 200 * For each bridge in the list, put the bridge and remove it from the list.
 201 * If list is empty, do nothing.
 202 */
 203void fpga_bridges_put(struct list_head *bridge_list)
 204{
 205        struct fpga_bridge *bridge;
 206        struct list_head *node, *next;
 207        unsigned long flags;
 208
 209        list_for_each_safe(node, next, bridge_list) {
 210                bridge = list_entry(node, struct fpga_bridge, node);
 211
 212                fpga_bridge_put(bridge);
 213
 214                spin_lock_irqsave(&bridge_list_lock, flags);
 215                list_del(&bridge->node);
 216                spin_unlock_irqrestore(&bridge_list_lock, flags);
 217        }
 218}
 219EXPORT_SYMBOL_GPL(fpga_bridges_put);
 220
 221/**
 222 * fpga_bridges_get_to_list - get a bridge, add it to a list
 223 *
 224 * @np: node pointer of a FPGA bridge
 225 * @info: fpga image specific information
 226 * @bridge_list: list of FPGA bridges
 227 *
 228 * Get an exclusive reference to the bridge and and it to the list.
 229 *
 230 * Return 0 for success, error code from of_fpga_bridge_get() othewise.
 231 */
 232int fpga_bridge_get_to_list(struct device_node *np,
 233                            struct fpga_image_info *info,
 234                            struct list_head *bridge_list)
 235{
 236        struct fpga_bridge *bridge;
 237        unsigned long flags;
 238
 239        bridge = of_fpga_bridge_get(np, info);
 240        if (IS_ERR(bridge))
 241                return PTR_ERR(bridge);
 242
 243        spin_lock_irqsave(&bridge_list_lock, flags);
 244        list_add(&bridge->node, bridge_list);
 245        spin_unlock_irqrestore(&bridge_list_lock, flags);
 246
 247        return 0;
 248}
 249EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list);
 250
 251static ssize_t name_show(struct device *dev,
 252                         struct device_attribute *attr, char *buf)
 253{
 254        struct fpga_bridge *bridge = to_fpga_bridge(dev);
 255
 256        return sprintf(buf, "%s\n", bridge->name);
 257}
 258
 259static ssize_t state_show(struct device *dev,
 260                          struct device_attribute *attr, char *buf)
 261{
 262        struct fpga_bridge *bridge = to_fpga_bridge(dev);
 263        int enable = 1;
 264
 265        if (bridge->br_ops && bridge->br_ops->enable_show)
 266                enable = bridge->br_ops->enable_show(bridge);
 267
 268        return sprintf(buf, "%s\n", enable ? "enabled" : "disabled");
 269}
 270
 271static DEVICE_ATTR_RO(name);
 272static DEVICE_ATTR_RO(state);
 273
 274#ifdef DEBUG
 275static ssize_t set_store(struct device *dev,
 276                        struct device_attribute *attr,
 277                        const char *buf, size_t count)
 278{
 279        struct fpga_bridge *bridge = to_fpga_bridge(dev);
 280        long enable;
 281        int ret;
 282
 283        ret = kstrtol(buf, 16, &enable);
 284        if (ret)
 285                return ret;
 286
 287        if (bridge->br_ops && bridge->br_ops->enable_set)
 288                enable = bridge->br_ops->enable_set(bridge, !!enable);
 289
 290        return count;
 291}
 292static DEVICE_ATTR_WO(set);
 293#endif
 294
 295static struct attribute *fpga_bridge_attrs[] = {
 296        &dev_attr_name.attr,
 297        &dev_attr_state.attr,
 298#ifdef DEBUG
 299        &dev_attr_set.attr,
 300#endif
 301        NULL,
 302};
 303ATTRIBUTE_GROUPS(fpga_bridge);
 304
 305/**
 306 * fpga_bridge_register - register a fpga bridge driver
 307 * @dev:        FPGA bridge device from pdev
 308 * @name:       FPGA bridge name
 309 * @br_ops:     pointer to structure of fpga bridge ops
 310 * @priv:       FPGA bridge private data
 311 *
 312 * Return: 0 for success, error code otherwise.
 313 */
 314int fpga_bridge_register(struct device *dev, const char *name,
 315                         const struct fpga_bridge_ops *br_ops, void *priv)
 316{
 317        struct fpga_bridge *bridge;
 318        int id, ret = 0;
 319
 320        if (!name || !strlen(name)) {
 321                dev_err(dev, "Attempt to register with no name!\n");
 322                return -EINVAL;
 323        }
 324
 325        bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
 326        if (!bridge)
 327                return -ENOMEM;
 328
 329        id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL);
 330        if (id < 0) {
 331                ret = id;
 332                goto error_kfree;
 333        }
 334
 335        mutex_init(&bridge->mutex);
 336        INIT_LIST_HEAD(&bridge->node);
 337
 338        bridge->name = name;
 339        bridge->br_ops = br_ops;
 340        bridge->priv = priv;
 341
 342        device_initialize(&bridge->dev);
 343        bridge->dev.class = fpga_bridge_class;
 344        bridge->dev.parent = dev;
 345        bridge->dev.of_node = dev->of_node;
 346        bridge->dev.id = id;
 347        dev_set_drvdata(dev, bridge);
 348
 349        ret = dev_set_name(&bridge->dev, "br%d", id);
 350        if (ret)
 351                goto error_device;
 352
 353        ret = device_add(&bridge->dev);
 354        if (ret)
 355                goto error_device;
 356
 357        of_platform_populate(dev->of_node, NULL, NULL, dev);
 358
 359        dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n",
 360                 bridge->name);
 361
 362        return 0;
 363
 364error_device:
 365        ida_simple_remove(&fpga_bridge_ida, id);
 366error_kfree:
 367        kfree(bridge);
 368
 369        return ret;
 370}
 371EXPORT_SYMBOL_GPL(fpga_bridge_register);
 372
 373/**
 374 * fpga_bridge_unregister - unregister a fpga bridge driver
 375 * @dev: FPGA bridge device from pdev
 376 */
 377void fpga_bridge_unregister(struct device *dev)
 378{
 379        struct fpga_bridge *bridge = dev_get_drvdata(dev);
 380
 381        /*
 382         * If the low level driver provides a method for putting bridge into
 383         * a desired state upon unregister, do it.
 384         */
 385        if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove)
 386                bridge->br_ops->fpga_bridge_remove(bridge);
 387
 388        device_unregister(&bridge->dev);
 389}
 390EXPORT_SYMBOL_GPL(fpga_bridge_unregister);
 391
 392static void fpga_bridge_dev_release(struct device *dev)
 393{
 394        struct fpga_bridge *bridge = to_fpga_bridge(dev);
 395
 396        ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
 397        kfree(bridge);
 398}
 399
 400static int __init fpga_bridge_dev_init(void)
 401{
 402        spin_lock_init(&bridge_list_lock);
 403
 404        fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge");
 405        if (IS_ERR(fpga_bridge_class))
 406                return PTR_ERR(fpga_bridge_class);
 407
 408        fpga_bridge_class->dev_groups = fpga_bridge_groups;
 409        fpga_bridge_class->dev_release = fpga_bridge_dev_release;
 410
 411        return 0;
 412}
 413
 414static void __exit fpga_bridge_dev_exit(void)
 415{
 416        class_destroy(fpga_bridge_class);
 417        ida_destroy(&fpga_bridge_ida);
 418}
 419
 420MODULE_DESCRIPTION("FPGA Bridge Driver");
 421MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
 422MODULE_LICENSE("GPL v2");
 423
 424subsys_initcall(fpga_bridge_dev_init);
 425module_exit(fpga_bridge_dev_exit);
 426