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 static DEFINE_IDA(fpga_bridge_ida); 27 static struct class *fpga_bridge_class; 28 29 /* Lock for adding/removing bridges to linked lists*/ 30 static spinlock_t bridge_list_lock; 31 32 static int fpga_bridge_of_node_match(struct device *dev, const void *data) 33 { 34 return dev->of_node == data; 35 } 36 37 /** 38 * fpga_bridge_enable - Enable transactions on the bridge 39 * 40 * @bridge: FPGA bridge 41 * 42 * Return: 0 for success, error code otherwise. 43 */ 44 int fpga_bridge_enable(struct fpga_bridge *bridge) 45 { 46 dev_dbg(&bridge->dev, "enable\n"); 47 48 if (bridge->br_ops && bridge->br_ops->enable_set) 49 return bridge->br_ops->enable_set(bridge, 1); 50 51 return 0; 52 } 53 EXPORT_SYMBOL_GPL(fpga_bridge_enable); 54 55 /** 56 * fpga_bridge_disable - Disable transactions on the bridge 57 * 58 * @bridge: FPGA bridge 59 * 60 * Return: 0 for success, error code otherwise. 61 */ 62 int fpga_bridge_disable(struct fpga_bridge *bridge) 63 { 64 dev_dbg(&bridge->dev, "disable\n"); 65 66 if (bridge->br_ops && bridge->br_ops->enable_set) 67 return bridge->br_ops->enable_set(bridge, 0); 68 69 return 0; 70 } 71 EXPORT_SYMBOL_GPL(fpga_bridge_disable); 72 73 /** 74 * of_fpga_bridge_get - get an exclusive reference to a fpga bridge 75 * 76 * @np: node pointer of a FPGA bridge 77 * @info: fpga image specific information 78 * 79 * Return fpga_bridge struct if successful. 80 * Return -EBUSY if someone already has a reference to the bridge. 81 * Return -ENODEV if @np is not a FPGA Bridge. 82 */ 83 struct fpga_bridge *of_fpga_bridge_get(struct device_node *np, 84 struct fpga_image_info *info) 85 86 { 87 struct device *dev; 88 struct fpga_bridge *bridge; 89 int ret = -ENODEV; 90 91 dev = class_find_device(fpga_bridge_class, NULL, np, 92 fpga_bridge_of_node_match); 93 if (!dev) 94 goto err_dev; 95 96 bridge = to_fpga_bridge(dev); 97 if (!bridge) 98 goto err_dev; 99 100 bridge->info = info; 101 102 if (!mutex_trylock(&bridge->mutex)) { 103 ret = -EBUSY; 104 goto err_dev; 105 } 106 107 if (!try_module_get(dev->parent->driver->owner)) 108 goto err_ll_mod; 109 110 dev_dbg(&bridge->dev, "get\n"); 111 112 return bridge; 113 114 err_ll_mod: 115 mutex_unlock(&bridge->mutex); 116 err_dev: 117 put_device(dev); 118 return ERR_PTR(ret); 119 } 120 EXPORT_SYMBOL_GPL(of_fpga_bridge_get); 121 122 /** 123 * fpga_bridge_put - release a reference to a bridge 124 * 125 * @bridge: FPGA bridge 126 */ 127 void fpga_bridge_put(struct fpga_bridge *bridge) 128 { 129 dev_dbg(&bridge->dev, "put\n"); 130 131 bridge->info = NULL; 132 module_put(bridge->dev.parent->driver->owner); 133 mutex_unlock(&bridge->mutex); 134 put_device(&bridge->dev); 135 } 136 EXPORT_SYMBOL_GPL(fpga_bridge_put); 137 138 /** 139 * fpga_bridges_enable - enable bridges in a list 140 * @bridge_list: list of FPGA bridges 141 * 142 * Enable each bridge in the list. If list is empty, do nothing. 143 * 144 * Return 0 for success or empty bridge list; return error code otherwise. 145 */ 146 int fpga_bridges_enable(struct list_head *bridge_list) 147 { 148 struct fpga_bridge *bridge; 149 int ret; 150 151 list_for_each_entry(bridge, bridge_list, node) { 152 ret = fpga_bridge_enable(bridge); 153 if (ret) 154 return ret; 155 } 156 157 return 0; 158 } 159 EXPORT_SYMBOL_GPL(fpga_bridges_enable); 160 161 /** 162 * fpga_bridges_disable - disable bridges in a list 163 * 164 * @bridge_list: list of FPGA bridges 165 * 166 * Disable each bridge in the list. If list is empty, do nothing. 167 * 168 * Return 0 for success or empty bridge list; return error code otherwise. 169 */ 170 int fpga_bridges_disable(struct list_head *bridge_list) 171 { 172 struct fpga_bridge *bridge; 173 int ret; 174 175 list_for_each_entry(bridge, bridge_list, node) { 176 ret = fpga_bridge_disable(bridge); 177 if (ret) 178 return ret; 179 } 180 181 return 0; 182 } 183 EXPORT_SYMBOL_GPL(fpga_bridges_disable); 184 185 /** 186 * fpga_bridges_put - put bridges 187 * 188 * @bridge_list: list of FPGA bridges 189 * 190 * For each bridge in the list, put the bridge and remove it from the list. 191 * If list is empty, do nothing. 192 */ 193 void fpga_bridges_put(struct list_head *bridge_list) 194 { 195 struct fpga_bridge *bridge, *next; 196 unsigned long flags; 197 198 list_for_each_entry_safe(bridge, next, bridge_list, node) { 199 fpga_bridge_put(bridge); 200 201 spin_lock_irqsave(&bridge_list_lock, flags); 202 list_del(&bridge->node); 203 spin_unlock_irqrestore(&bridge_list_lock, flags); 204 } 205 } 206 EXPORT_SYMBOL_GPL(fpga_bridges_put); 207 208 /** 209 * fpga_bridges_get_to_list - get a bridge, add it to a list 210 * 211 * @np: node pointer of a FPGA bridge 212 * @info: fpga image specific information 213 * @bridge_list: list of FPGA bridges 214 * 215 * Get an exclusive reference to the bridge and and it to the list. 216 * 217 * Return 0 for success, error code from of_fpga_bridge_get() othewise. 218 */ 219 int fpga_bridge_get_to_list(struct device_node *np, 220 struct fpga_image_info *info, 221 struct list_head *bridge_list) 222 { 223 struct fpga_bridge *bridge; 224 unsigned long flags; 225 226 bridge = of_fpga_bridge_get(np, info); 227 if (IS_ERR(bridge)) 228 return PTR_ERR(bridge); 229 230 spin_lock_irqsave(&bridge_list_lock, flags); 231 list_add(&bridge->node, bridge_list); 232 spin_unlock_irqrestore(&bridge_list_lock, flags); 233 234 return 0; 235 } 236 EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list); 237 238 static ssize_t name_show(struct device *dev, 239 struct device_attribute *attr, char *buf) 240 { 241 struct fpga_bridge *bridge = to_fpga_bridge(dev); 242 243 return sprintf(buf, "%s\n", bridge->name); 244 } 245 246 static ssize_t state_show(struct device *dev, 247 struct device_attribute *attr, char *buf) 248 { 249 struct fpga_bridge *bridge = to_fpga_bridge(dev); 250 int enable = 1; 251 252 if (bridge->br_ops && bridge->br_ops->enable_show) 253 enable = bridge->br_ops->enable_show(bridge); 254 255 return sprintf(buf, "%s\n", enable ? "enabled" : "disabled"); 256 } 257 258 static DEVICE_ATTR_RO(name); 259 static DEVICE_ATTR_RO(state); 260 261 static struct attribute *fpga_bridge_attrs[] = { 262 &dev_attr_name.attr, 263 &dev_attr_state.attr, 264 NULL, 265 }; 266 ATTRIBUTE_GROUPS(fpga_bridge); 267 268 /** 269 * fpga_bridge_register - register a fpga bridge driver 270 * @dev: FPGA bridge device from pdev 271 * @name: FPGA bridge name 272 * @br_ops: pointer to structure of fpga bridge ops 273 * @priv: FPGA bridge private data 274 * 275 * Return: 0 for success, error code otherwise. 276 */ 277 int fpga_bridge_register(struct device *dev, const char *name, 278 const struct fpga_bridge_ops *br_ops, void *priv) 279 { 280 struct fpga_bridge *bridge; 281 int id, ret = 0; 282 283 if (!name || !strlen(name)) { 284 dev_err(dev, "Attempt to register with no name!\n"); 285 return -EINVAL; 286 } 287 288 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); 289 if (!bridge) 290 return -ENOMEM; 291 292 id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); 293 if (id < 0) { 294 ret = id; 295 goto error_kfree; 296 } 297 298 mutex_init(&bridge->mutex); 299 INIT_LIST_HEAD(&bridge->node); 300 301 bridge->name = name; 302 bridge->br_ops = br_ops; 303 bridge->priv = priv; 304 305 device_initialize(&bridge->dev); 306 bridge->dev.class = fpga_bridge_class; 307 bridge->dev.parent = dev; 308 bridge->dev.of_node = dev->of_node; 309 bridge->dev.id = id; 310 dev_set_drvdata(dev, bridge); 311 312 ret = dev_set_name(&bridge->dev, "br%d", id); 313 if (ret) 314 goto error_device; 315 316 ret = device_add(&bridge->dev); 317 if (ret) 318 goto error_device; 319 320 of_platform_populate(dev->of_node, NULL, NULL, dev); 321 322 dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n", 323 bridge->name); 324 325 return 0; 326 327 error_device: 328 ida_simple_remove(&fpga_bridge_ida, id); 329 error_kfree: 330 kfree(bridge); 331 332 return ret; 333 } 334 EXPORT_SYMBOL_GPL(fpga_bridge_register); 335 336 /** 337 * fpga_bridge_unregister - unregister a fpga bridge driver 338 * @dev: FPGA bridge device from pdev 339 */ 340 void fpga_bridge_unregister(struct device *dev) 341 { 342 struct fpga_bridge *bridge = dev_get_drvdata(dev); 343 344 /* 345 * If the low level driver provides a method for putting bridge into 346 * a desired state upon unregister, do it. 347 */ 348 if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove) 349 bridge->br_ops->fpga_bridge_remove(bridge); 350 351 device_unregister(&bridge->dev); 352 } 353 EXPORT_SYMBOL_GPL(fpga_bridge_unregister); 354 355 static void fpga_bridge_dev_release(struct device *dev) 356 { 357 struct fpga_bridge *bridge = to_fpga_bridge(dev); 358 359 ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); 360 kfree(bridge); 361 } 362 363 static int __init fpga_bridge_dev_init(void) 364 { 365 spin_lock_init(&bridge_list_lock); 366 367 fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge"); 368 if (IS_ERR(fpga_bridge_class)) 369 return PTR_ERR(fpga_bridge_class); 370 371 fpga_bridge_class->dev_groups = fpga_bridge_groups; 372 fpga_bridge_class->dev_release = fpga_bridge_dev_release; 373 374 return 0; 375 } 376 377 static void __exit fpga_bridge_dev_exit(void) 378 { 379 class_destroy(fpga_bridge_class); 380 ida_destroy(&fpga_bridge_ida); 381 } 382 383 MODULE_DESCRIPTION("FPGA Bridge Driver"); 384 MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); 385 MODULE_LICENSE("GPL v2"); 386 387 subsys_initcall(fpga_bridge_dev_init); 388 module_exit(fpga_bridge_dev_exit); 389