1 /* 2 * FPGA Region - Device Tree support for FPGA programming under Linux 3 * 4 * Copyright (C) 2013-2016 Altera Corporation 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 19 #include <linux/fpga/fpga-bridge.h> 20 #include <linux/fpga/fpga-mgr.h> 21 #include <linux/idr.h> 22 #include <linux/kernel.h> 23 #include <linux/list.h> 24 #include <linux/module.h> 25 #include <linux/of_platform.h> 26 #include <linux/slab.h> 27 #include <linux/spinlock.h> 28 29 /** 30 * struct fpga_region - FPGA Region structure 31 * @dev: FPGA Region device 32 * @mutex: enforces exclusive reference to region 33 * @bridge_list: list of FPGA bridges specified in region 34 * @info: fpga image specific information 35 */ 36 struct fpga_region { 37 struct device dev; 38 struct mutex mutex; /* for exclusive reference to region */ 39 struct list_head bridge_list; 40 struct fpga_image_info *info; 41 }; 42 43 #define to_fpga_region(d) container_of(d, struct fpga_region, dev) 44 45 static DEFINE_IDA(fpga_region_ida); 46 static struct class *fpga_region_class; 47 48 static const struct of_device_id fpga_region_of_match[] = { 49 { .compatible = "fpga-region", }, 50 {}, 51 }; 52 MODULE_DEVICE_TABLE(of, fpga_region_of_match); 53 54 static int fpga_region_of_node_match(struct device *dev, const void *data) 55 { 56 return dev->of_node == data; 57 } 58 59 /** 60 * fpga_region_find - find FPGA region 61 * @np: device node of FPGA Region 62 * Caller will need to put_device(®ion->dev) when done. 63 * Returns FPGA Region struct or NULL 64 */ 65 static struct fpga_region *fpga_region_find(struct device_node *np) 66 { 67 struct device *dev; 68 69 dev = class_find_device(fpga_region_class, NULL, np, 70 fpga_region_of_node_match); 71 if (!dev) 72 return NULL; 73 74 return to_fpga_region(dev); 75 } 76 77 /** 78 * fpga_region_get - get an exclusive reference to a fpga region 79 * @region: FPGA Region struct 80 * 81 * Caller should call fpga_region_put() when done with region. 82 * 83 * Return fpga_region struct if successful. 84 * Return -EBUSY if someone already has a reference to the region. 85 * Return -ENODEV if @np is not a FPGA Region. 86 */ 87 static struct fpga_region *fpga_region_get(struct fpga_region *region) 88 { 89 struct device *dev = ®ion->dev; 90 91 if (!mutex_trylock(®ion->mutex)) { 92 dev_dbg(dev, "%s: FPGA Region already in use\n", __func__); 93 return ERR_PTR(-EBUSY); 94 } 95 96 get_device(dev); 97 of_node_get(dev->of_node); 98 if (!try_module_get(dev->parent->driver->owner)) { 99 of_node_put(dev->of_node); 100 put_device(dev); 101 mutex_unlock(®ion->mutex); 102 return ERR_PTR(-ENODEV); 103 } 104 105 dev_dbg(®ion->dev, "get\n"); 106 107 return region; 108 } 109 110 /** 111 * fpga_region_put - release a reference to a region 112 * 113 * @region: FPGA region 114 */ 115 static void fpga_region_put(struct fpga_region *region) 116 { 117 struct device *dev = ®ion->dev; 118 119 dev_dbg(®ion->dev, "put\n"); 120 121 module_put(dev->parent->driver->owner); 122 of_node_put(dev->of_node); 123 put_device(dev); 124 mutex_unlock(®ion->mutex); 125 } 126 127 /** 128 * fpga_region_get_manager - get exclusive reference for FPGA manager 129 * @region: FPGA region 130 * 131 * Get FPGA Manager from "fpga-mgr" property or from ancestor region. 132 * 133 * Caller should call fpga_mgr_put() when done with manager. 134 * 135 * Return: fpga manager struct or IS_ERR() condition containing error code. 136 */ 137 static struct fpga_manager *fpga_region_get_manager(struct fpga_region *region) 138 { 139 struct device *dev = ®ion->dev; 140 struct device_node *np = dev->of_node; 141 struct device_node *mgr_node; 142 struct fpga_manager *mgr; 143 144 of_node_get(np); 145 while (np) { 146 if (of_device_is_compatible(np, "fpga-region")) { 147 mgr_node = of_parse_phandle(np, "fpga-mgr", 0); 148 if (mgr_node) { 149 mgr = of_fpga_mgr_get(mgr_node); 150 of_node_put(np); 151 return mgr; 152 } 153 } 154 np = of_get_next_parent(np); 155 } 156 of_node_put(np); 157 158 return ERR_PTR(-EINVAL); 159 } 160 161 /** 162 * fpga_region_get_bridges - create a list of bridges 163 * @region: FPGA region 164 * @overlay: device node of the overlay 165 * 166 * Create a list of bridges including the parent bridge and the bridges 167 * specified by "fpga-bridges" property. Note that the 168 * fpga_bridges_enable/disable/put functions are all fine with an empty list 169 * if that happens. 170 * 171 * Caller should call fpga_bridges_put(®ion->bridge_list) when 172 * done with the bridges. 173 * 174 * Return 0 for success (even if there are no bridges specified) 175 * or -EBUSY if any of the bridges are in use. 176 */ 177 static int fpga_region_get_bridges(struct fpga_region *region, 178 struct device_node *overlay) 179 { 180 struct device *dev = ®ion->dev; 181 struct device_node *region_np = dev->of_node; 182 struct device_node *br, *np, *parent_br = NULL; 183 int i, ret; 184 185 /* If parent is a bridge, add to list */ 186 ret = fpga_bridge_get_to_list(region_np->parent, region->info, 187 ®ion->bridge_list); 188 if (ret == -EBUSY) 189 return ret; 190 191 if (!ret) 192 parent_br = region_np->parent; 193 194 /* If overlay has a list of bridges, use it. */ 195 if (of_parse_phandle(overlay, "fpga-bridges", 0)) 196 np = overlay; 197 else 198 np = region_np; 199 200 for (i = 0; ; i++) { 201 br = of_parse_phandle(np, "fpga-bridges", i); 202 if (!br) 203 break; 204 205 /* If parent bridge is in list, skip it. */ 206 if (br == parent_br) 207 continue; 208 209 /* If node is a bridge, get it and add to list */ 210 ret = fpga_bridge_get_to_list(br, region->info, 211 ®ion->bridge_list); 212 213 /* If any of the bridges are in use, give up */ 214 if (ret == -EBUSY) { 215 fpga_bridges_put(®ion->bridge_list); 216 return -EBUSY; 217 } 218 } 219 220 return 0; 221 } 222 223 /** 224 * fpga_region_program_fpga - program FPGA 225 * @region: FPGA region 226 * @firmware_name: name of FPGA image firmware file 227 * @overlay: device node of the overlay 228 * Program an FPGA using information in the device tree. 229 * Function assumes that there is a firmware-name property. 230 * Return 0 for success or negative error code. 231 */ 232 static int fpga_region_program_fpga(struct fpga_region *region, 233 const char *firmware_name, 234 struct device_node *overlay) 235 { 236 struct fpga_manager *mgr; 237 int ret; 238 239 region = fpga_region_get(region); 240 if (IS_ERR(region)) { 241 pr_err("failed to get fpga region\n"); 242 return PTR_ERR(region); 243 } 244 245 mgr = fpga_region_get_manager(region); 246 if (IS_ERR(mgr)) { 247 pr_err("failed to get fpga region manager\n"); 248 return PTR_ERR(mgr); 249 } 250 251 ret = fpga_region_get_bridges(region, overlay); 252 if (ret) { 253 pr_err("failed to get fpga region bridges\n"); 254 goto err_put_mgr; 255 } 256 257 ret = fpga_bridges_disable(®ion->bridge_list); 258 if (ret) { 259 pr_err("failed to disable region bridges\n"); 260 goto err_put_br; 261 } 262 263 ret = fpga_mgr_firmware_load(mgr, region->info, firmware_name); 264 if (ret) { 265 pr_err("failed to load fpga image\n"); 266 goto err_put_br; 267 } 268 269 ret = fpga_bridges_enable(®ion->bridge_list); 270 if (ret) { 271 pr_err("failed to enable region bridges\n"); 272 goto err_put_br; 273 } 274 275 fpga_mgr_put(mgr); 276 fpga_region_put(region); 277 278 return 0; 279 280 err_put_br: 281 fpga_bridges_put(®ion->bridge_list); 282 err_put_mgr: 283 fpga_mgr_put(mgr); 284 fpga_region_put(region); 285 286 return ret; 287 } 288 289 /** 290 * child_regions_with_firmware 291 * @overlay: device node of the overlay 292 * 293 * If the overlay adds child FPGA regions, they are not allowed to have 294 * firmware-name property. 295 * 296 * Return 0 for OK or -EINVAL if child FPGA region adds firmware-name. 297 */ 298 static int child_regions_with_firmware(struct device_node *overlay) 299 { 300 struct device_node *child_region; 301 const char *child_firmware_name; 302 int ret = 0; 303 304 of_node_get(overlay); 305 306 child_region = of_find_matching_node(overlay, fpga_region_of_match); 307 while (child_region) { 308 if (!of_property_read_string(child_region, "firmware-name", 309 &child_firmware_name)) { 310 ret = -EINVAL; 311 break; 312 } 313 child_region = of_find_matching_node(child_region, 314 fpga_region_of_match); 315 } 316 317 of_node_put(child_region); 318 319 if (ret) 320 pr_err("firmware-name not allowed in child FPGA region: %s", 321 child_region->full_name); 322 323 return ret; 324 } 325 326 /** 327 * fpga_region_notify_pre_apply - pre-apply overlay notification 328 * 329 * @region: FPGA region that the overlay was applied to 330 * @nd: overlay notification data 331 * 332 * Called after when an overlay targeted to a FPGA Region is about to be 333 * applied. Function will check the properties that will be added to the FPGA 334 * region. If the checks pass, it will program the FPGA. 335 * 336 * The checks are: 337 * The overlay must add either firmware-name or external-fpga-config property 338 * to the FPGA Region. 339 * 340 * firmware-name : program the FPGA 341 * external-fpga-config : FPGA is already programmed 342 * 343 * The overlay can add other FPGA regions, but child FPGA regions cannot have a 344 * firmware-name property since those regions don't exist yet. 345 * 346 * If the overlay that breaks the rules, notifier returns an error and the 347 * overlay is rejected before it goes into the main tree. 348 * 349 * Returns 0 for success or negative error code for failure. 350 */ 351 static int fpga_region_notify_pre_apply(struct fpga_region *region, 352 struct of_overlay_notify_data *nd) 353 { 354 const char *firmware_name = NULL; 355 struct fpga_image_info *info; 356 int ret; 357 358 info = devm_kzalloc(®ion->dev, sizeof(*info), GFP_KERNEL); 359 if (!info) 360 return -ENOMEM; 361 362 region->info = info; 363 364 /* Reject overlay if child FPGA Regions have firmware-name property */ 365 ret = child_regions_with_firmware(nd->overlay); 366 if (ret) 367 return ret; 368 369 /* Read FPGA region properties from the overlay */ 370 if (of_property_read_bool(nd->overlay, "partial-fpga-config")) 371 info->flags |= FPGA_MGR_PARTIAL_RECONFIG; 372 373 if (of_property_read_bool(nd->overlay, "external-fpga-config")) 374 info->flags |= FPGA_MGR_EXTERNAL_CONFIG; 375 376 of_property_read_string(nd->overlay, "firmware-name", &firmware_name); 377 378 of_property_read_u32(nd->overlay, "region-unfreeze-timeout-us", 379 &info->enable_timeout_us); 380 381 of_property_read_u32(nd->overlay, "region-freeze-timeout-us", 382 &info->disable_timeout_us); 383 384 /* If FPGA was externally programmed, don't specify firmware */ 385 if ((info->flags & FPGA_MGR_EXTERNAL_CONFIG) && firmware_name) { 386 pr_err("error: specified firmware and external-fpga-config"); 387 return -EINVAL; 388 } 389 390 /* FPGA is already configured externally. We're done. */ 391 if (info->flags & FPGA_MGR_EXTERNAL_CONFIG) 392 return 0; 393 394 /* If we got this far, we should be programming the FPGA */ 395 if (!firmware_name) { 396 pr_err("should specify firmware-name or external-fpga-config\n"); 397 return -EINVAL; 398 } 399 400 return fpga_region_program_fpga(region, firmware_name, nd->overlay); 401 } 402 403 /** 404 * fpga_region_notify_post_remove - post-remove overlay notification 405 * 406 * @region: FPGA region that was targeted by the overlay that was removed 407 * @nd: overlay notification data 408 * 409 * Called after an overlay has been removed if the overlay's target was a 410 * FPGA region. 411 */ 412 static void fpga_region_notify_post_remove(struct fpga_region *region, 413 struct of_overlay_notify_data *nd) 414 { 415 fpga_bridges_disable(®ion->bridge_list); 416 fpga_bridges_put(®ion->bridge_list); 417 devm_kfree(®ion->dev, region->info); 418 region->info = NULL; 419 } 420 421 /** 422 * of_fpga_region_notify - reconfig notifier for dynamic DT changes 423 * @nb: notifier block 424 * @action: notifier action 425 * @arg: reconfig data 426 * 427 * This notifier handles programming a FPGA when a "firmware-name" property is 428 * added to a fpga-region. 429 * 430 * Returns NOTIFY_OK or error if FPGA programming fails. 431 */ 432 static int of_fpga_region_notify(struct notifier_block *nb, 433 unsigned long action, void *arg) 434 { 435 struct of_overlay_notify_data *nd = arg; 436 struct fpga_region *region; 437 int ret; 438 439 switch (action) { 440 case OF_OVERLAY_PRE_APPLY: 441 pr_debug("%s OF_OVERLAY_PRE_APPLY\n", __func__); 442 break; 443 case OF_OVERLAY_POST_APPLY: 444 pr_debug("%s OF_OVERLAY_POST_APPLY\n", __func__); 445 return NOTIFY_OK; /* not for us */ 446 case OF_OVERLAY_PRE_REMOVE: 447 pr_debug("%s OF_OVERLAY_PRE_REMOVE\n", __func__); 448 return NOTIFY_OK; /* not for us */ 449 case OF_OVERLAY_POST_REMOVE: 450 pr_debug("%s OF_OVERLAY_POST_REMOVE\n", __func__); 451 break; 452 default: /* should not happen */ 453 return NOTIFY_OK; 454 } 455 456 region = fpga_region_find(nd->target); 457 if (!region) 458 return NOTIFY_OK; 459 460 ret = 0; 461 switch (action) { 462 case OF_OVERLAY_PRE_APPLY: 463 ret = fpga_region_notify_pre_apply(region, nd); 464 break; 465 466 case OF_OVERLAY_POST_REMOVE: 467 fpga_region_notify_post_remove(region, nd); 468 break; 469 } 470 471 put_device(®ion->dev); 472 473 if (ret) 474 return notifier_from_errno(ret); 475 476 return NOTIFY_OK; 477 } 478 479 static struct notifier_block fpga_region_of_nb = { 480 .notifier_call = of_fpga_region_notify, 481 }; 482 483 static int fpga_region_probe(struct platform_device *pdev) 484 { 485 struct device *dev = &pdev->dev; 486 struct device_node *np = dev->of_node; 487 struct fpga_region *region; 488 int id, ret = 0; 489 490 region = kzalloc(sizeof(*region), GFP_KERNEL); 491 if (!region) 492 return -ENOMEM; 493 494 id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL); 495 if (id < 0) { 496 ret = id; 497 goto err_kfree; 498 } 499 500 mutex_init(®ion->mutex); 501 INIT_LIST_HEAD(®ion->bridge_list); 502 503 device_initialize(®ion->dev); 504 region->dev.class = fpga_region_class; 505 region->dev.parent = dev; 506 region->dev.of_node = np; 507 region->dev.id = id; 508 dev_set_drvdata(dev, region); 509 510 ret = dev_set_name(®ion->dev, "region%d", id); 511 if (ret) 512 goto err_remove; 513 514 ret = device_add(®ion->dev); 515 if (ret) 516 goto err_remove; 517 518 of_platform_populate(np, fpga_region_of_match, NULL, ®ion->dev); 519 520 dev_info(dev, "FPGA Region probed\n"); 521 522 return 0; 523 524 err_remove: 525 ida_simple_remove(&fpga_region_ida, id); 526 err_kfree: 527 kfree(region); 528 529 return ret; 530 } 531 532 static int fpga_region_remove(struct platform_device *pdev) 533 { 534 struct fpga_region *region = platform_get_drvdata(pdev); 535 536 device_unregister(®ion->dev); 537 538 return 0; 539 } 540 541 static struct platform_driver fpga_region_driver = { 542 .probe = fpga_region_probe, 543 .remove = fpga_region_remove, 544 .driver = { 545 .name = "fpga-region", 546 .of_match_table = of_match_ptr(fpga_region_of_match), 547 }, 548 }; 549 550 static void fpga_region_dev_release(struct device *dev) 551 { 552 struct fpga_region *region = to_fpga_region(dev); 553 554 ida_simple_remove(&fpga_region_ida, region->dev.id); 555 kfree(region); 556 } 557 558 /** 559 * fpga_region_init - init function for fpga_region class 560 * Creates the fpga_region class and registers a reconfig notifier. 561 */ 562 static int __init fpga_region_init(void) 563 { 564 int ret; 565 566 fpga_region_class = class_create(THIS_MODULE, "fpga_region"); 567 if (IS_ERR(fpga_region_class)) 568 return PTR_ERR(fpga_region_class); 569 570 fpga_region_class->dev_release = fpga_region_dev_release; 571 572 ret = of_overlay_notifier_register(&fpga_region_of_nb); 573 if (ret) 574 goto err_class; 575 576 ret = platform_driver_register(&fpga_region_driver); 577 if (ret) 578 goto err_plat; 579 580 return 0; 581 582 err_plat: 583 of_overlay_notifier_unregister(&fpga_region_of_nb); 584 err_class: 585 class_destroy(fpga_region_class); 586 ida_destroy(&fpga_region_ida); 587 return ret; 588 } 589 590 static void __exit fpga_region_exit(void) 591 { 592 platform_driver_unregister(&fpga_region_driver); 593 of_overlay_notifier_unregister(&fpga_region_of_nb); 594 class_destroy(fpga_region_class); 595 ida_destroy(&fpga_region_ida); 596 } 597 598 subsys_initcall(fpga_region_init); 599 module_exit(fpga_region_exit); 600 601 MODULE_DESCRIPTION("FPGA Region"); 602 MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); 603 MODULE_LICENSE("GPL v2"); 604