1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for FPGA Device Feature List (DFL) Support 4 * 5 * Copyright (C) 2017-2018 Intel Corporation, Inc. 6 * 7 * Authors: 8 * Kang Luwei <luwei.kang@intel.com> 9 * Zhang Yi <yi.z.zhang@intel.com> 10 * Wu Hao <hao.wu@intel.com> 11 * Xiao Guangrong <guangrong.xiao@linux.intel.com> 12 */ 13 #include <linux/module.h> 14 15 #include "dfl.h" 16 17 static DEFINE_MUTEX(dfl_id_mutex); 18 19 /* 20 * when adding a new feature dev support in DFL framework, it's required to 21 * add a new item in enum dfl_id_type and provide related information in below 22 * dfl_devs table which is indexed by dfl_id_type, e.g. name string used for 23 * platform device creation (define name strings in dfl.h, as they could be 24 * reused by platform device drivers). 25 * 26 * if the new feature dev needs chardev support, then it's required to add 27 * a new item in dfl_chardevs table and configure dfl_devs[i].devt_type as 28 * index to dfl_chardevs table. If no chardev support just set devt_type 29 * as one invalid index (DFL_FPGA_DEVT_MAX). 30 */ 31 enum dfl_id_type { 32 FME_ID, /* fme id allocation and mapping */ 33 PORT_ID, /* port id allocation and mapping */ 34 DFL_ID_MAX, 35 }; 36 37 enum dfl_fpga_devt_type { 38 DFL_FPGA_DEVT_FME, 39 DFL_FPGA_DEVT_PORT, 40 DFL_FPGA_DEVT_MAX, 41 }; 42 43 static struct lock_class_key dfl_pdata_keys[DFL_ID_MAX]; 44 45 static const char *dfl_pdata_key_strings[DFL_ID_MAX] = { 46 "dfl-fme-pdata", 47 "dfl-port-pdata", 48 }; 49 50 /** 51 * dfl_dev_info - dfl feature device information. 52 * @name: name string of the feature platform device. 53 * @dfh_id: id value in Device Feature Header (DFH) register by DFL spec. 54 * @id: idr id of the feature dev. 55 * @devt_type: index to dfl_chrdevs[]. 56 */ 57 struct dfl_dev_info { 58 const char *name; 59 u32 dfh_id; 60 struct idr id; 61 enum dfl_fpga_devt_type devt_type; 62 }; 63 64 /* it is indexed by dfl_id_type */ 65 static struct dfl_dev_info dfl_devs[] = { 66 {.name = DFL_FPGA_FEATURE_DEV_FME, .dfh_id = DFH_ID_FIU_FME, 67 .devt_type = DFL_FPGA_DEVT_FME}, 68 {.name = DFL_FPGA_FEATURE_DEV_PORT, .dfh_id = DFH_ID_FIU_PORT, 69 .devt_type = DFL_FPGA_DEVT_PORT}, 70 }; 71 72 /** 73 * dfl_chardev_info - chardev information of dfl feature device 74 * @name: nmae string of the char device. 75 * @devt: devt of the char device. 76 */ 77 struct dfl_chardev_info { 78 const char *name; 79 dev_t devt; 80 }; 81 82 /* indexed by enum dfl_fpga_devt_type */ 83 static struct dfl_chardev_info dfl_chrdevs[] = { 84 {.name = DFL_FPGA_FEATURE_DEV_FME}, 85 {.name = DFL_FPGA_FEATURE_DEV_PORT}, 86 }; 87 88 static void dfl_ids_init(void) 89 { 90 int i; 91 92 for (i = 0; i < ARRAY_SIZE(dfl_devs); i++) 93 idr_init(&dfl_devs[i].id); 94 } 95 96 static void dfl_ids_destroy(void) 97 { 98 int i; 99 100 for (i = 0; i < ARRAY_SIZE(dfl_devs); i++) 101 idr_destroy(&dfl_devs[i].id); 102 } 103 104 static int dfl_id_alloc(enum dfl_id_type type, struct device *dev) 105 { 106 int id; 107 108 WARN_ON(type >= DFL_ID_MAX); 109 mutex_lock(&dfl_id_mutex); 110 id = idr_alloc(&dfl_devs[type].id, dev, 0, 0, GFP_KERNEL); 111 mutex_unlock(&dfl_id_mutex); 112 113 return id; 114 } 115 116 static void dfl_id_free(enum dfl_id_type type, int id) 117 { 118 WARN_ON(type >= DFL_ID_MAX); 119 mutex_lock(&dfl_id_mutex); 120 idr_remove(&dfl_devs[type].id, id); 121 mutex_unlock(&dfl_id_mutex); 122 } 123 124 static enum dfl_id_type feature_dev_id_type(struct platform_device *pdev) 125 { 126 int i; 127 128 for (i = 0; i < ARRAY_SIZE(dfl_devs); i++) 129 if (!strcmp(dfl_devs[i].name, pdev->name)) 130 return i; 131 132 return DFL_ID_MAX; 133 } 134 135 static enum dfl_id_type dfh_id_to_type(u32 id) 136 { 137 int i; 138 139 for (i = 0; i < ARRAY_SIZE(dfl_devs); i++) 140 if (dfl_devs[i].dfh_id == id) 141 return i; 142 143 return DFL_ID_MAX; 144 } 145 146 /* 147 * introduce a global port_ops list, it allows port drivers to register ops 148 * in such list, then other feature devices (e.g. FME), could use the port 149 * functions even related port platform device is hidden. Below is one example, 150 * in virtualization case of PCIe-based FPGA DFL device, when SRIOV is 151 * enabled, port (and it's AFU) is turned into VF and port platform device 152 * is hidden from system but it's still required to access port to finish FPGA 153 * reconfiguration function in FME. 154 */ 155 156 static DEFINE_MUTEX(dfl_port_ops_mutex); 157 static LIST_HEAD(dfl_port_ops_list); 158 159 /** 160 * dfl_fpga_port_ops_get - get matched port ops from the global list 161 * @pdev: platform device to match with associated port ops. 162 * Return: matched port ops on success, NULL otherwise. 163 * 164 * Please note that must dfl_fpga_port_ops_put after use the port_ops. 165 */ 166 struct dfl_fpga_port_ops *dfl_fpga_port_ops_get(struct platform_device *pdev) 167 { 168 struct dfl_fpga_port_ops *ops = NULL; 169 170 mutex_lock(&dfl_port_ops_mutex); 171 if (list_empty(&dfl_port_ops_list)) 172 goto done; 173 174 list_for_each_entry(ops, &dfl_port_ops_list, node) { 175 /* match port_ops using the name of platform device */ 176 if (!strcmp(pdev->name, ops->name)) { 177 if (!try_module_get(ops->owner)) 178 ops = NULL; 179 goto done; 180 } 181 } 182 183 ops = NULL; 184 done: 185 mutex_unlock(&dfl_port_ops_mutex); 186 return ops; 187 } 188 EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_get); 189 190 /** 191 * dfl_fpga_port_ops_put - put port ops 192 * @ops: port ops. 193 */ 194 void dfl_fpga_port_ops_put(struct dfl_fpga_port_ops *ops) 195 { 196 if (ops && ops->owner) 197 module_put(ops->owner); 198 } 199 EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_put); 200 201 /** 202 * dfl_fpga_port_ops_add - add port_ops to global list 203 * @ops: port ops to add. 204 */ 205 void dfl_fpga_port_ops_add(struct dfl_fpga_port_ops *ops) 206 { 207 mutex_lock(&dfl_port_ops_mutex); 208 list_add_tail(&ops->node, &dfl_port_ops_list); 209 mutex_unlock(&dfl_port_ops_mutex); 210 } 211 EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_add); 212 213 /** 214 * dfl_fpga_port_ops_del - remove port_ops from global list 215 * @ops: port ops to del. 216 */ 217 void dfl_fpga_port_ops_del(struct dfl_fpga_port_ops *ops) 218 { 219 mutex_lock(&dfl_port_ops_mutex); 220 list_del(&ops->node); 221 mutex_unlock(&dfl_port_ops_mutex); 222 } 223 EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_del); 224 225 /** 226 * dfl_fpga_check_port_id - check the port id 227 * @pdev: port platform device. 228 * @pport_id: port id to compare. 229 * 230 * Return: 1 if port device matches with given port id, otherwise 0. 231 */ 232 int dfl_fpga_check_port_id(struct platform_device *pdev, void *pport_id) 233 { 234 struct dfl_fpga_port_ops *port_ops = dfl_fpga_port_ops_get(pdev); 235 int port_id; 236 237 if (!port_ops || !port_ops->get_id) 238 return 0; 239 240 port_id = port_ops->get_id(pdev); 241 dfl_fpga_port_ops_put(port_ops); 242 243 return port_id == *(int *)pport_id; 244 } 245 EXPORT_SYMBOL_GPL(dfl_fpga_check_port_id); 246 247 /** 248 * dfl_fpga_dev_feature_uinit - uinit for sub features of dfl feature device 249 * @pdev: feature device. 250 */ 251 void dfl_fpga_dev_feature_uinit(struct platform_device *pdev) 252 { 253 struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev); 254 struct dfl_feature *feature; 255 256 dfl_fpga_dev_for_each_feature(pdata, feature) 257 if (feature->ops) { 258 feature->ops->uinit(pdev, feature); 259 feature->ops = NULL; 260 } 261 } 262 EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_uinit); 263 264 static int dfl_feature_instance_init(struct platform_device *pdev, 265 struct dfl_feature_platform_data *pdata, 266 struct dfl_feature *feature, 267 struct dfl_feature_driver *drv) 268 { 269 int ret; 270 271 ret = drv->ops->init(pdev, feature); 272 if (ret) 273 return ret; 274 275 feature->ops = drv->ops; 276 277 return ret; 278 } 279 280 /** 281 * dfl_fpga_dev_feature_init - init for sub features of dfl feature device 282 * @pdev: feature device. 283 * @feature_drvs: drvs for sub features. 284 * 285 * This function will match sub features with given feature drvs list and 286 * use matched drv to init related sub feature. 287 * 288 * Return: 0 on success, negative error code otherwise. 289 */ 290 int dfl_fpga_dev_feature_init(struct platform_device *pdev, 291 struct dfl_feature_driver *feature_drvs) 292 { 293 struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev); 294 struct dfl_feature_driver *drv = feature_drvs; 295 struct dfl_feature *feature; 296 int ret; 297 298 while (drv->ops) { 299 dfl_fpga_dev_for_each_feature(pdata, feature) { 300 /* match feature and drv using id */ 301 if (feature->id == drv->id) { 302 ret = dfl_feature_instance_init(pdev, pdata, 303 feature, drv); 304 if (ret) 305 goto exit; 306 } 307 } 308 drv++; 309 } 310 311 return 0; 312 exit: 313 dfl_fpga_dev_feature_uinit(pdev); 314 return ret; 315 } 316 EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_init); 317 318 static void dfl_chardev_uinit(void) 319 { 320 int i; 321 322 for (i = 0; i < DFL_FPGA_DEVT_MAX; i++) 323 if (MAJOR(dfl_chrdevs[i].devt)) { 324 unregister_chrdev_region(dfl_chrdevs[i].devt, 325 MINORMASK + 1); 326 dfl_chrdevs[i].devt = MKDEV(0, 0); 327 } 328 } 329 330 static int dfl_chardev_init(void) 331 { 332 int i, ret; 333 334 for (i = 0; i < DFL_FPGA_DEVT_MAX; i++) { 335 ret = alloc_chrdev_region(&dfl_chrdevs[i].devt, 0, 336 MINORMASK + 1, dfl_chrdevs[i].name); 337 if (ret) 338 goto exit; 339 } 340 341 return 0; 342 343 exit: 344 dfl_chardev_uinit(); 345 return ret; 346 } 347 348 static dev_t dfl_get_devt(enum dfl_fpga_devt_type type, int id) 349 { 350 if (type >= DFL_FPGA_DEVT_MAX) 351 return 0; 352 353 return MKDEV(MAJOR(dfl_chrdevs[type].devt), id); 354 } 355 356 /** 357 * dfl_fpga_dev_ops_register - register cdev ops for feature dev 358 * 359 * @pdev: feature dev. 360 * @fops: file operations for feature dev's cdev. 361 * @owner: owning module/driver. 362 * 363 * Return: 0 on success, negative error code otherwise. 364 */ 365 int dfl_fpga_dev_ops_register(struct platform_device *pdev, 366 const struct file_operations *fops, 367 struct module *owner) 368 { 369 struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev); 370 371 cdev_init(&pdata->cdev, fops); 372 pdata->cdev.owner = owner; 373 374 /* 375 * set parent to the feature device so that its refcount is 376 * decreased after the last refcount of cdev is gone, that 377 * makes sure the feature device is valid during device 378 * file's life-cycle. 379 */ 380 pdata->cdev.kobj.parent = &pdev->dev.kobj; 381 382 return cdev_add(&pdata->cdev, pdev->dev.devt, 1); 383 } 384 EXPORT_SYMBOL_GPL(dfl_fpga_dev_ops_register); 385 386 /** 387 * dfl_fpga_dev_ops_unregister - unregister cdev ops for feature dev 388 * @pdev: feature dev. 389 */ 390 void dfl_fpga_dev_ops_unregister(struct platform_device *pdev) 391 { 392 struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev); 393 394 cdev_del(&pdata->cdev); 395 } 396 EXPORT_SYMBOL_GPL(dfl_fpga_dev_ops_unregister); 397 398 /** 399 * struct build_feature_devs_info - info collected during feature dev build. 400 * 401 * @dev: device to enumerate. 402 * @cdev: the container device for all feature devices. 403 * @feature_dev: current feature device. 404 * @ioaddr: header register region address of feature device in enumeration. 405 * @sub_features: a sub features linked list for feature device in enumeration. 406 * @feature_num: number of sub features for feature device in enumeration. 407 */ 408 struct build_feature_devs_info { 409 struct device *dev; 410 struct dfl_fpga_cdev *cdev; 411 struct platform_device *feature_dev; 412 void __iomem *ioaddr; 413 struct list_head sub_features; 414 int feature_num; 415 }; 416 417 /** 418 * struct dfl_feature_info - sub feature info collected during feature dev build 419 * 420 * @fid: id of this sub feature. 421 * @mmio_res: mmio resource of this sub feature. 422 * @ioaddr: mapped base address of mmio resource. 423 * @node: node in sub_features linked list. 424 */ 425 struct dfl_feature_info { 426 u64 fid; 427 struct resource mmio_res; 428 void __iomem *ioaddr; 429 struct list_head node; 430 }; 431 432 static void dfl_fpga_cdev_add_port_dev(struct dfl_fpga_cdev *cdev, 433 struct platform_device *port) 434 { 435 struct dfl_feature_platform_data *pdata = dev_get_platdata(&port->dev); 436 437 mutex_lock(&cdev->lock); 438 list_add(&pdata->node, &cdev->port_dev_list); 439 get_device(&pdata->dev->dev); 440 mutex_unlock(&cdev->lock); 441 } 442 443 /* 444 * register current feature device, it is called when we need to switch to 445 * another feature parsing or we have parsed all features on given device 446 * feature list. 447 */ 448 static int build_info_commit_dev(struct build_feature_devs_info *binfo) 449 { 450 struct platform_device *fdev = binfo->feature_dev; 451 struct dfl_feature_platform_data *pdata; 452 struct dfl_feature_info *finfo, *p; 453 enum dfl_id_type type; 454 int ret, index = 0; 455 456 if (!fdev) 457 return 0; 458 459 type = feature_dev_id_type(fdev); 460 if (WARN_ON_ONCE(type >= DFL_ID_MAX)) 461 return -EINVAL; 462 463 /* 464 * we do not need to care for the memory which is associated with 465 * the platform device. After calling platform_device_unregister(), 466 * it will be automatically freed by device's release() callback, 467 * platform_device_release(). 468 */ 469 pdata = kzalloc(dfl_feature_platform_data_size(binfo->feature_num), 470 GFP_KERNEL); 471 if (!pdata) 472 return -ENOMEM; 473 474 pdata->dev = fdev; 475 pdata->num = binfo->feature_num; 476 pdata->dfl_cdev = binfo->cdev; 477 mutex_init(&pdata->lock); 478 lockdep_set_class_and_name(&pdata->lock, &dfl_pdata_keys[type], 479 dfl_pdata_key_strings[type]); 480 481 /* 482 * the count should be initialized to 0 to make sure 483 *__fpga_port_enable() following __fpga_port_disable() 484 * works properly for port device. 485 * and it should always be 0 for fme device. 486 */ 487 WARN_ON(pdata->disable_count); 488 489 fdev->dev.platform_data = pdata; 490 491 /* each sub feature has one MMIO resource */ 492 fdev->num_resources = binfo->feature_num; 493 fdev->resource = kcalloc(binfo->feature_num, sizeof(*fdev->resource), 494 GFP_KERNEL); 495 if (!fdev->resource) 496 return -ENOMEM; 497 498 /* fill features and resource information for feature dev */ 499 list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) { 500 struct dfl_feature *feature = &pdata->features[index]; 501 502 /* save resource information for each feature */ 503 feature->id = finfo->fid; 504 feature->resource_index = index; 505 feature->ioaddr = finfo->ioaddr; 506 fdev->resource[index++] = finfo->mmio_res; 507 508 list_del(&finfo->node); 509 kfree(finfo); 510 } 511 512 ret = platform_device_add(binfo->feature_dev); 513 if (!ret) { 514 if (type == PORT_ID) 515 dfl_fpga_cdev_add_port_dev(binfo->cdev, 516 binfo->feature_dev); 517 else 518 binfo->cdev->fme_dev = 519 get_device(&binfo->feature_dev->dev); 520 /* 521 * reset it to avoid build_info_free() freeing their resource. 522 * 523 * The resource of successfully registered feature devices 524 * will be freed by platform_device_unregister(). See the 525 * comments in build_info_create_dev(). 526 */ 527 binfo->feature_dev = NULL; 528 } 529 530 return ret; 531 } 532 533 static int 534 build_info_create_dev(struct build_feature_devs_info *binfo, 535 enum dfl_id_type type, void __iomem *ioaddr) 536 { 537 struct platform_device *fdev; 538 int ret; 539 540 if (type >= DFL_ID_MAX) 541 return -EINVAL; 542 543 /* we will create a new device, commit current device first */ 544 ret = build_info_commit_dev(binfo); 545 if (ret) 546 return ret; 547 548 /* 549 * we use -ENODEV as the initialization indicator which indicates 550 * whether the id need to be reclaimed 551 */ 552 fdev = platform_device_alloc(dfl_devs[type].name, -ENODEV); 553 if (!fdev) 554 return -ENOMEM; 555 556 binfo->feature_dev = fdev; 557 binfo->feature_num = 0; 558 binfo->ioaddr = ioaddr; 559 INIT_LIST_HEAD(&binfo->sub_features); 560 561 fdev->id = dfl_id_alloc(type, &fdev->dev); 562 if (fdev->id < 0) 563 return fdev->id; 564 565 fdev->dev.parent = &binfo->cdev->region->dev; 566 fdev->dev.devt = dfl_get_devt(dfl_devs[type].devt_type, fdev->id); 567 568 return 0; 569 } 570 571 static void build_info_free(struct build_feature_devs_info *binfo) 572 { 573 struct dfl_feature_info *finfo, *p; 574 575 /* 576 * it is a valid id, free it. See comments in 577 * build_info_create_dev() 578 */ 579 if (binfo->feature_dev && binfo->feature_dev->id >= 0) { 580 dfl_id_free(feature_dev_id_type(binfo->feature_dev), 581 binfo->feature_dev->id); 582 583 list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) { 584 list_del(&finfo->node); 585 kfree(finfo); 586 } 587 } 588 589 platform_device_put(binfo->feature_dev); 590 591 devm_kfree(binfo->dev, binfo); 592 } 593 594 static inline u32 feature_size(void __iomem *start) 595 { 596 u64 v = readq(start + DFH); 597 u32 ofst = FIELD_GET(DFH_NEXT_HDR_OFST, v); 598 /* workaround for private features with invalid size, use 4K instead */ 599 return ofst ? ofst : 4096; 600 } 601 602 static u64 feature_id(void __iomem *start) 603 { 604 u64 v = readq(start + DFH); 605 u16 id = FIELD_GET(DFH_ID, v); 606 u8 type = FIELD_GET(DFH_TYPE, v); 607 608 if (type == DFH_TYPE_FIU) 609 return FEATURE_ID_FIU_HEADER; 610 else if (type == DFH_TYPE_PRIVATE) 611 return id; 612 else if (type == DFH_TYPE_AFU) 613 return FEATURE_ID_AFU; 614 615 WARN_ON(1); 616 return 0; 617 } 618 619 /* 620 * when create sub feature instances, for private features, it doesn't need 621 * to provide resource size and feature id as they could be read from DFH 622 * register. For afu sub feature, its register region only contains user 623 * defined registers, so never trust any information from it, just use the 624 * resource size information provided by its parent FIU. 625 */ 626 static int 627 create_feature_instance(struct build_feature_devs_info *binfo, 628 struct dfl_fpga_enum_dfl *dfl, resource_size_t ofst, 629 resource_size_t size, u64 fid) 630 { 631 struct dfl_feature_info *finfo; 632 633 /* read feature size and id if inputs are invalid */ 634 size = size ? size : feature_size(dfl->ioaddr + ofst); 635 fid = fid ? fid : feature_id(dfl->ioaddr + ofst); 636 637 if (dfl->len - ofst < size) 638 return -EINVAL; 639 640 finfo = kzalloc(sizeof(*finfo), GFP_KERNEL); 641 if (!finfo) 642 return -ENOMEM; 643 644 finfo->fid = fid; 645 finfo->mmio_res.start = dfl->start + ofst; 646 finfo->mmio_res.end = finfo->mmio_res.start + size - 1; 647 finfo->mmio_res.flags = IORESOURCE_MEM; 648 finfo->ioaddr = dfl->ioaddr + ofst; 649 650 list_add_tail(&finfo->node, &binfo->sub_features); 651 binfo->feature_num++; 652 653 return 0; 654 } 655 656 static int parse_feature_port_afu(struct build_feature_devs_info *binfo, 657 struct dfl_fpga_enum_dfl *dfl, 658 resource_size_t ofst) 659 { 660 u64 v = readq(binfo->ioaddr + PORT_HDR_CAP); 661 u32 size = FIELD_GET(PORT_CAP_MMIO_SIZE, v) << 10; 662 663 WARN_ON(!size); 664 665 return create_feature_instance(binfo, dfl, ofst, size, FEATURE_ID_AFU); 666 } 667 668 static int parse_feature_afu(struct build_feature_devs_info *binfo, 669 struct dfl_fpga_enum_dfl *dfl, 670 resource_size_t ofst) 671 { 672 if (!binfo->feature_dev) { 673 dev_err(binfo->dev, "this AFU does not belong to any FIU.\n"); 674 return -EINVAL; 675 } 676 677 switch (feature_dev_id_type(binfo->feature_dev)) { 678 case PORT_ID: 679 return parse_feature_port_afu(binfo, dfl, ofst); 680 default: 681 dev_info(binfo->dev, "AFU belonging to FIU %s is not supported yet.\n", 682 binfo->feature_dev->name); 683 } 684 685 return 0; 686 } 687 688 static int parse_feature_fiu(struct build_feature_devs_info *binfo, 689 struct dfl_fpga_enum_dfl *dfl, 690 resource_size_t ofst) 691 { 692 u32 id, offset; 693 u64 v; 694 int ret = 0; 695 696 v = readq(dfl->ioaddr + ofst + DFH); 697 id = FIELD_GET(DFH_ID, v); 698 699 /* create platform device for dfl feature dev */ 700 ret = build_info_create_dev(binfo, dfh_id_to_type(id), 701 dfl->ioaddr + ofst); 702 if (ret) 703 return ret; 704 705 ret = create_feature_instance(binfo, dfl, ofst, 0, 0); 706 if (ret) 707 return ret; 708 /* 709 * find and parse FIU's child AFU via its NEXT_AFU register. 710 * please note that only Port has valid NEXT_AFU pointer per spec. 711 */ 712 v = readq(dfl->ioaddr + ofst + NEXT_AFU); 713 714 offset = FIELD_GET(NEXT_AFU_NEXT_DFH_OFST, v); 715 if (offset) 716 return parse_feature_afu(binfo, dfl, ofst + offset); 717 718 dev_dbg(binfo->dev, "No AFUs detected on FIU %d\n", id); 719 720 return ret; 721 } 722 723 static int parse_feature_private(struct build_feature_devs_info *binfo, 724 struct dfl_fpga_enum_dfl *dfl, 725 resource_size_t ofst) 726 { 727 if (!binfo->feature_dev) { 728 dev_err(binfo->dev, "the private feature %llx does not belong to any AFU.\n", 729 (unsigned long long)feature_id(dfl->ioaddr + ofst)); 730 return -EINVAL; 731 } 732 733 return create_feature_instance(binfo, dfl, ofst, 0, 0); 734 } 735 736 /** 737 * parse_feature - parse a feature on given device feature list 738 * 739 * @binfo: build feature devices information. 740 * @dfl: device feature list to parse 741 * @ofst: offset to feature header on this device feature list 742 */ 743 static int parse_feature(struct build_feature_devs_info *binfo, 744 struct dfl_fpga_enum_dfl *dfl, resource_size_t ofst) 745 { 746 u64 v; 747 u32 type; 748 749 v = readq(dfl->ioaddr + ofst + DFH); 750 type = FIELD_GET(DFH_TYPE, v); 751 752 switch (type) { 753 case DFH_TYPE_AFU: 754 return parse_feature_afu(binfo, dfl, ofst); 755 case DFH_TYPE_PRIVATE: 756 return parse_feature_private(binfo, dfl, ofst); 757 case DFH_TYPE_FIU: 758 return parse_feature_fiu(binfo, dfl, ofst); 759 default: 760 dev_info(binfo->dev, 761 "Feature Type %x is not supported.\n", type); 762 } 763 764 return 0; 765 } 766 767 static int parse_feature_list(struct build_feature_devs_info *binfo, 768 struct dfl_fpga_enum_dfl *dfl) 769 { 770 void __iomem *start = dfl->ioaddr; 771 void __iomem *end = dfl->ioaddr + dfl->len; 772 int ret = 0; 773 u32 ofst = 0; 774 u64 v; 775 776 /* walk through the device feature list via DFH's next DFH pointer. */ 777 for (; start < end; start += ofst) { 778 if (end - start < DFH_SIZE) { 779 dev_err(binfo->dev, "The region is too small to contain a feature.\n"); 780 return -EINVAL; 781 } 782 783 ret = parse_feature(binfo, dfl, start - dfl->ioaddr); 784 if (ret) 785 return ret; 786 787 v = readq(start + DFH); 788 ofst = FIELD_GET(DFH_NEXT_HDR_OFST, v); 789 790 /* stop parsing if EOL(End of List) is set or offset is 0 */ 791 if ((v & DFH_EOL) || !ofst) 792 break; 793 } 794 795 /* commit current feature device when reach the end of list */ 796 return build_info_commit_dev(binfo); 797 } 798 799 struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct device *dev) 800 { 801 struct dfl_fpga_enum_info *info; 802 803 get_device(dev); 804 805 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 806 if (!info) { 807 put_device(dev); 808 return NULL; 809 } 810 811 info->dev = dev; 812 INIT_LIST_HEAD(&info->dfls); 813 814 return info; 815 } 816 EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_alloc); 817 818 void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info) 819 { 820 struct dfl_fpga_enum_dfl *tmp, *dfl; 821 struct device *dev; 822 823 if (!info) 824 return; 825 826 dev = info->dev; 827 828 /* remove all device feature lists in the list. */ 829 list_for_each_entry_safe(dfl, tmp, &info->dfls, node) { 830 list_del(&dfl->node); 831 devm_kfree(dev, dfl); 832 } 833 834 devm_kfree(dev, info); 835 put_device(dev); 836 } 837 EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_free); 838 839 /** 840 * dfl_fpga_enum_info_add_dfl - add info of a device feature list to enum info 841 * 842 * @info: ptr to dfl_fpga_enum_info 843 * @start: mmio resource address of the device feature list. 844 * @len: mmio resource length of the device feature list. 845 * @ioaddr: mapped mmio resource address of the device feature list. 846 * 847 * One FPGA device may have one or more Device Feature Lists (DFLs), use this 848 * function to add information of each DFL to common data structure for next 849 * step enumeration. 850 * 851 * Return: 0 on success, negative error code otherwise. 852 */ 853 int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info, 854 resource_size_t start, resource_size_t len, 855 void __iomem *ioaddr) 856 { 857 struct dfl_fpga_enum_dfl *dfl; 858 859 dfl = devm_kzalloc(info->dev, sizeof(*dfl), GFP_KERNEL); 860 if (!dfl) 861 return -ENOMEM; 862 863 dfl->start = start; 864 dfl->len = len; 865 dfl->ioaddr = ioaddr; 866 867 list_add_tail(&dfl->node, &info->dfls); 868 869 return 0; 870 } 871 EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_add_dfl); 872 873 static int remove_feature_dev(struct device *dev, void *data) 874 { 875 struct platform_device *pdev = to_platform_device(dev); 876 enum dfl_id_type type = feature_dev_id_type(pdev); 877 int id = pdev->id; 878 879 platform_device_unregister(pdev); 880 881 dfl_id_free(type, id); 882 883 return 0; 884 } 885 886 static void remove_feature_devs(struct dfl_fpga_cdev *cdev) 887 { 888 device_for_each_child(&cdev->region->dev, NULL, remove_feature_dev); 889 } 890 891 /** 892 * dfl_fpga_feature_devs_enumerate - enumerate feature devices 893 * @info: information for enumeration. 894 * 895 * This function creates a container device (base FPGA region), enumerates 896 * feature devices based on the enumeration info and creates platform devices 897 * under the container device. 898 * 899 * Return: dfl_fpga_cdev struct on success, -errno on failure 900 */ 901 struct dfl_fpga_cdev * 902 dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info) 903 { 904 struct build_feature_devs_info *binfo; 905 struct dfl_fpga_enum_dfl *dfl; 906 struct dfl_fpga_cdev *cdev; 907 int ret = 0; 908 909 if (!info->dev) 910 return ERR_PTR(-ENODEV); 911 912 cdev = devm_kzalloc(info->dev, sizeof(*cdev), GFP_KERNEL); 913 if (!cdev) 914 return ERR_PTR(-ENOMEM); 915 916 cdev->region = devm_fpga_region_create(info->dev, NULL, NULL); 917 if (!cdev->region) { 918 ret = -ENOMEM; 919 goto free_cdev_exit; 920 } 921 922 cdev->parent = info->dev; 923 mutex_init(&cdev->lock); 924 INIT_LIST_HEAD(&cdev->port_dev_list); 925 926 ret = fpga_region_register(cdev->region); 927 if (ret) 928 goto free_cdev_exit; 929 930 /* create and init build info for enumeration */ 931 binfo = devm_kzalloc(info->dev, sizeof(*binfo), GFP_KERNEL); 932 if (!binfo) { 933 ret = -ENOMEM; 934 goto unregister_region_exit; 935 } 936 937 binfo->dev = info->dev; 938 binfo->cdev = cdev; 939 940 /* 941 * start enumeration for all feature devices based on Device Feature 942 * Lists. 943 */ 944 list_for_each_entry(dfl, &info->dfls, node) { 945 ret = parse_feature_list(binfo, dfl); 946 if (ret) { 947 remove_feature_devs(cdev); 948 build_info_free(binfo); 949 goto unregister_region_exit; 950 } 951 } 952 953 build_info_free(binfo); 954 955 return cdev; 956 957 unregister_region_exit: 958 fpga_region_unregister(cdev->region); 959 free_cdev_exit: 960 devm_kfree(info->dev, cdev); 961 return ERR_PTR(ret); 962 } 963 EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_enumerate); 964 965 /** 966 * dfl_fpga_feature_devs_remove - remove all feature devices 967 * @cdev: fpga container device. 968 * 969 * Remove the container device and all feature devices under given container 970 * devices. 971 */ 972 void dfl_fpga_feature_devs_remove(struct dfl_fpga_cdev *cdev) 973 { 974 struct dfl_feature_platform_data *pdata, *ptmp; 975 976 remove_feature_devs(cdev); 977 978 mutex_lock(&cdev->lock); 979 if (cdev->fme_dev) { 980 /* the fme should be unregistered. */ 981 WARN_ON(device_is_registered(cdev->fme_dev)); 982 put_device(cdev->fme_dev); 983 } 984 985 list_for_each_entry_safe(pdata, ptmp, &cdev->port_dev_list, node) { 986 struct platform_device *port_dev = pdata->dev; 987 988 /* the port should be unregistered. */ 989 WARN_ON(device_is_registered(&port_dev->dev)); 990 list_del(&pdata->node); 991 put_device(&port_dev->dev); 992 } 993 mutex_unlock(&cdev->lock); 994 995 fpga_region_unregister(cdev->region); 996 devm_kfree(cdev->parent, cdev); 997 } 998 EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_remove); 999 1000 /** 1001 * __dfl_fpga_cdev_find_port - find a port under given container device 1002 * 1003 * @cdev: container device 1004 * @data: data passed to match function 1005 * @match: match function used to find specific port from the port device list 1006 * 1007 * Find a port device under container device. This function needs to be 1008 * invoked with lock held. 1009 * 1010 * Return: pointer to port's platform device if successful, NULL otherwise. 1011 * 1012 * NOTE: you will need to drop the device reference with put_device() after use. 1013 */ 1014 struct platform_device * 1015 __dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data, 1016 int (*match)(struct platform_device *, void *)) 1017 { 1018 struct dfl_feature_platform_data *pdata; 1019 struct platform_device *port_dev; 1020 1021 list_for_each_entry(pdata, &cdev->port_dev_list, node) { 1022 port_dev = pdata->dev; 1023 1024 if (match(port_dev, data) && get_device(&port_dev->dev)) 1025 return port_dev; 1026 } 1027 1028 return NULL; 1029 } 1030 EXPORT_SYMBOL_GPL(__dfl_fpga_cdev_find_port); 1031 1032 static int __init dfl_fpga_init(void) 1033 { 1034 int ret; 1035 1036 dfl_ids_init(); 1037 1038 ret = dfl_chardev_init(); 1039 if (ret) 1040 dfl_ids_destroy(); 1041 1042 return ret; 1043 } 1044 1045 static void __exit dfl_fpga_exit(void) 1046 { 1047 dfl_chardev_uinit(); 1048 dfl_ids_destroy(); 1049 } 1050 1051 module_init(dfl_fpga_init); 1052 module_exit(dfl_fpga_exit); 1053 1054 MODULE_DESCRIPTION("FPGA Device Feature List (DFL) Support"); 1055 MODULE_AUTHOR("Intel Corporation"); 1056 MODULE_LICENSE("GPL v2"); 1057