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 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 struct list_head *node; 150 int ret; 151 152 list_for_each(node, bridge_list) { 153 bridge = list_entry(node, struct fpga_bridge, node); 154 ret = fpga_bridge_enable(bridge); 155 if (ret) 156 return ret; 157 } 158 159 return 0; 160 } 161 EXPORT_SYMBOL_GPL(fpga_bridges_enable); 162 163 /** 164 * fpga_bridges_disable - disable bridges in a list 165 * 166 * @bridge_list: list of FPGA bridges 167 * 168 * Disable each bridge in the list. If list is empty, do nothing. 169 * 170 * Return 0 for success or empty bridge list; return error code otherwise. 171 */ 172 int fpga_bridges_disable(struct list_head *bridge_list) 173 { 174 struct fpga_bridge *bridge; 175 struct list_head *node; 176 int ret; 177 178 list_for_each(node, bridge_list) { 179 bridge = list_entry(node, struct fpga_bridge, node); 180 ret = fpga_bridge_disable(bridge); 181 if (ret) 182 return ret; 183 } 184 185 return 0; 186 } 187 EXPORT_SYMBOL_GPL(fpga_bridges_disable); 188 189 /** 190 * fpga_bridges_put - put bridges 191 * 192 * @bridge_list: list of FPGA bridges 193 * 194 * For each bridge in the list, put the bridge and remove it from the list. 195 * If list is empty, do nothing. 196 */ 197 void fpga_bridges_put(struct list_head *bridge_list) 198 { 199 struct fpga_bridge *bridge; 200 struct list_head *node, *next; 201 unsigned long flags; 202 203 list_for_each_safe(node, next, bridge_list) { 204 bridge = list_entry(node, struct fpga_bridge, node); 205 206 fpga_bridge_put(bridge); 207 208 spin_lock_irqsave(&bridge_list_lock, flags); 209 list_del(&bridge->node); 210 spin_unlock_irqrestore(&bridge_list_lock, flags); 211 } 212 } 213 EXPORT_SYMBOL_GPL(fpga_bridges_put); 214 215 /** 216 * fpga_bridges_get_to_list - get a bridge, add it to a list 217 * 218 * @np: node pointer of a FPGA bridge 219 * @info: fpga image specific information 220 * @bridge_list: list of FPGA bridges 221 * 222 * Get an exclusive reference to the bridge and and it to the list. 223 * 224 * Return 0 for success, error code from of_fpga_bridge_get() othewise. 225 */ 226 int fpga_bridge_get_to_list(struct device_node *np, 227 struct fpga_image_info *info, 228 struct list_head *bridge_list) 229 { 230 struct fpga_bridge *bridge; 231 unsigned long flags; 232 233 bridge = of_fpga_bridge_get(np, info); 234 if (IS_ERR(bridge)) 235 return PTR_ERR(bridge); 236 237 spin_lock_irqsave(&bridge_list_lock, flags); 238 list_add(&bridge->node, bridge_list); 239 spin_unlock_irqrestore(&bridge_list_lock, flags); 240 241 return 0; 242 } 243 EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list); 244 245 static ssize_t name_show(struct device *dev, 246 struct device_attribute *attr, char *buf) 247 { 248 struct fpga_bridge *bridge = to_fpga_bridge(dev); 249 250 return sprintf(buf, "%s\n", bridge->name); 251 } 252 253 static ssize_t state_show(struct device *dev, 254 struct device_attribute *attr, char *buf) 255 { 256 struct fpga_bridge *bridge = to_fpga_bridge(dev); 257 int enable = 1; 258 259 if (bridge->br_ops && bridge->br_ops->enable_show) 260 enable = bridge->br_ops->enable_show(bridge); 261 262 return sprintf(buf, "%s\n", enable ? "enabled" : "disabled"); 263 } 264 265 static DEVICE_ATTR_RO(name); 266 static DEVICE_ATTR_RO(state); 267 268 static struct attribute *fpga_bridge_attrs[] = { 269 &dev_attr_name.attr, 270 &dev_attr_state.attr, 271 NULL, 272 }; 273 ATTRIBUTE_GROUPS(fpga_bridge); 274 275 /** 276 * fpga_bridge_register - register a fpga bridge driver 277 * @dev: FPGA bridge device from pdev 278 * @name: FPGA bridge name 279 * @br_ops: pointer to structure of fpga bridge ops 280 * @priv: FPGA bridge private data 281 * 282 * Return: 0 for success, error code otherwise. 283 */ 284 int fpga_bridge_register(struct device *dev, const char *name, 285 const struct fpga_bridge_ops *br_ops, void *priv) 286 { 287 struct fpga_bridge *bridge; 288 int id, ret = 0; 289 290 if (!name || !strlen(name)) { 291 dev_err(dev, "Attempt to register with no name!\n"); 292 return -EINVAL; 293 } 294 295 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); 296 if (!bridge) 297 return -ENOMEM; 298 299 id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); 300 if (id < 0) { 301 ret = id; 302 goto error_kfree; 303 } 304 305 mutex_init(&bridge->mutex); 306 INIT_LIST_HEAD(&bridge->node); 307 308 bridge->name = name; 309 bridge->br_ops = br_ops; 310 bridge->priv = priv; 311 312 device_initialize(&bridge->dev); 313 bridge->dev.class = fpga_bridge_class; 314 bridge->dev.parent = dev; 315 bridge->dev.of_node = dev->of_node; 316 bridge->dev.id = id; 317 dev_set_drvdata(dev, bridge); 318 319 ret = dev_set_name(&bridge->dev, "br%d", id); 320 if (ret) 321 goto error_device; 322 323 ret = device_add(&bridge->dev); 324 if (ret) 325 goto error_device; 326 327 of_platform_populate(dev->of_node, NULL, NULL, dev); 328 329 dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n", 330 bridge->name); 331 332 return 0; 333 334 error_device: 335 ida_simple_remove(&fpga_bridge_ida, id); 336 error_kfree: 337 kfree(bridge); 338 339 return ret; 340 } 341 EXPORT_SYMBOL_GPL(fpga_bridge_register); 342 343 /** 344 * fpga_bridge_unregister - unregister a fpga bridge driver 345 * @dev: FPGA bridge device from pdev 346 */ 347 void fpga_bridge_unregister(struct device *dev) 348 { 349 struct fpga_bridge *bridge = dev_get_drvdata(dev); 350 351 /* 352 * If the low level driver provides a method for putting bridge into 353 * a desired state upon unregister, do it. 354 */ 355 if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove) 356 bridge->br_ops->fpga_bridge_remove(bridge); 357 358 device_unregister(&bridge->dev); 359 } 360 EXPORT_SYMBOL_GPL(fpga_bridge_unregister); 361 362 static void fpga_bridge_dev_release(struct device *dev) 363 { 364 struct fpga_bridge *bridge = to_fpga_bridge(dev); 365 366 ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); 367 kfree(bridge); 368 } 369 370 static int __init fpga_bridge_dev_init(void) 371 { 372 spin_lock_init(&bridge_list_lock); 373 374 fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge"); 375 if (IS_ERR(fpga_bridge_class)) 376 return PTR_ERR(fpga_bridge_class); 377 378 fpga_bridge_class->dev_groups = fpga_bridge_groups; 379 fpga_bridge_class->dev_release = fpga_bridge_dev_release; 380 381 return 0; 382 } 383 384 static void __exit fpga_bridge_dev_exit(void) 385 { 386 class_destroy(fpga_bridge_class); 387 ida_destroy(&fpga_bridge_ida); 388 } 389 390 MODULE_DESCRIPTION("FPGA Bridge Driver"); 391 MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); 392 MODULE_LICENSE("GPL v2"); 393 394 subsys_initcall(fpga_bridge_dev_init); 395 module_exit(fpga_bridge_dev_exit); 396