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