diff options
author | Alan Tull <atull@kernel.org> | 2018-05-16 19:49:55 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-05-25 12:23:55 -0400 |
commit | 7085e2a94f7df5f419e3cfb2fe809ce6564e9629 (patch) | |
tree | b0609f2d091aae39e00609357d5e6de678887bef /drivers/fpga/fpga-mgr.c | |
parent | bbaa9cd3a605e337cefc566e5ac1b110763c8d1c (diff) |
fpga: manager: change api, don't use drvdata
Change fpga_mgr_register to not set or use drvdata. This supports
the case where a PCIe device has more than one manager.
Add fpga_mgr_create/free functions. Change fpga_mgr_register and
fpga_mgr_unregister functions to take the mgr struct as their only
parameter.
struct fpga_manager *fpga_mgr_create(struct device *dev,
const char *name,
const struct fpga_manager_ops *mops,
void *priv);
void fpga_mgr_free(struct fpga_manager *mgr);
int fpga_mgr_register(struct fpga_manager *mgr);
void fpga_mgr_unregister(struct fpga_manager *mgr);
Update the drivers that call fpga_mgr_register with the new API.
Signed-off-by: Alan Tull <atull@kernel.org>
[Moritz: Fixup whitespace issue]
Reported-by: Jiuyue Ma <majiuyue@huawei.com>
Signed-off-by: Moritz Fischer <mdf@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/fpga/fpga-mgr.c')
-rw-r--r-- | drivers/fpga/fpga-mgr.c | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index 9939d2cbc9a6..0a5181db3e2b 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c | |||
@@ -515,17 +515,17 @@ void fpga_mgr_unlock(struct fpga_manager *mgr) | |||
515 | EXPORT_SYMBOL_GPL(fpga_mgr_unlock); | 515 | EXPORT_SYMBOL_GPL(fpga_mgr_unlock); |
516 | 516 | ||
517 | /** | 517 | /** |
518 | * fpga_mgr_register - register a low level fpga manager driver | 518 | * fpga_mgr_create - create and initialize a FPGA manager struct |
519 | * @dev: fpga manager device from pdev | 519 | * @dev: fpga manager device from pdev |
520 | * @name: fpga manager name | 520 | * @name: fpga manager name |
521 | * @mops: pointer to structure of fpga manager ops | 521 | * @mops: pointer to structure of fpga manager ops |
522 | * @priv: fpga manager private data | 522 | * @priv: fpga manager private data |
523 | * | 523 | * |
524 | * Return: 0 on success, negative error code otherwise. | 524 | * Return: pointer to struct fpga_manager or NULL |
525 | */ | 525 | */ |
526 | int fpga_mgr_register(struct device *dev, const char *name, | 526 | struct fpga_manager *fpga_mgr_create(struct device *dev, const char *name, |
527 | const struct fpga_manager_ops *mops, | 527 | const struct fpga_manager_ops *mops, |
528 | void *priv) | 528 | void *priv) |
529 | { | 529 | { |
530 | struct fpga_manager *mgr; | 530 | struct fpga_manager *mgr; |
531 | int id, ret; | 531 | int id, ret; |
@@ -534,17 +534,17 @@ int fpga_mgr_register(struct device *dev, const char *name, | |||
534 | !mops->write_init || (!mops->write && !mops->write_sg) || | 534 | !mops->write_init || (!mops->write && !mops->write_sg) || |
535 | (mops->write && mops->write_sg)) { | 535 | (mops->write && mops->write_sg)) { |
536 | dev_err(dev, "Attempt to register without fpga_manager_ops\n"); | 536 | dev_err(dev, "Attempt to register without fpga_manager_ops\n"); |
537 | return -EINVAL; | 537 | return NULL; |
538 | } | 538 | } |
539 | 539 | ||
540 | if (!name || !strlen(name)) { | 540 | if (!name || !strlen(name)) { |
541 | dev_err(dev, "Attempt to register with no name!\n"); | 541 | dev_err(dev, "Attempt to register with no name!\n"); |
542 | return -EINVAL; | 542 | return NULL; |
543 | } | 543 | } |
544 | 544 | ||
545 | mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); | 545 | mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); |
546 | if (!mgr) | 546 | if (!mgr) |
547 | return -ENOMEM; | 547 | return NULL; |
548 | 548 | ||
549 | id = ida_simple_get(&fpga_mgr_ida, 0, 0, GFP_KERNEL); | 549 | id = ida_simple_get(&fpga_mgr_ida, 0, 0, GFP_KERNEL); |
550 | if (id < 0) { | 550 | if (id < 0) { |
@@ -558,25 +558,56 @@ int fpga_mgr_register(struct device *dev, const char *name, | |||
558 | mgr->mops = mops; | 558 | mgr->mops = mops; |
559 | mgr->priv = priv; | 559 | mgr->priv = priv; |
560 | 560 | ||
561 | /* | ||
562 | * Initialize framework state by requesting low level driver read state | ||
563 | * from device. FPGA may be in reset mode or may have been programmed | ||
564 | * by bootloader or EEPROM. | ||
565 | */ | ||
566 | mgr->state = mgr->mops->state(mgr); | ||
567 | |||
568 | device_initialize(&mgr->dev); | 561 | device_initialize(&mgr->dev); |
569 | mgr->dev.class = fpga_mgr_class; | 562 | mgr->dev.class = fpga_mgr_class; |
570 | mgr->dev.groups = mops->groups; | 563 | mgr->dev.groups = mops->groups; |
571 | mgr->dev.parent = dev; | 564 | mgr->dev.parent = dev; |
572 | mgr->dev.of_node = dev->of_node; | 565 | mgr->dev.of_node = dev->of_node; |
573 | mgr->dev.id = id; | 566 | mgr->dev.id = id; |
574 | dev_set_drvdata(dev, mgr); | ||
575 | 567 | ||
576 | ret = dev_set_name(&mgr->dev, "fpga%d", id); | 568 | ret = dev_set_name(&mgr->dev, "fpga%d", id); |
577 | if (ret) | 569 | if (ret) |
578 | goto error_device; | 570 | goto error_device; |
579 | 571 | ||
572 | return mgr; | ||
573 | |||
574 | error_device: | ||
575 | ida_simple_remove(&fpga_mgr_ida, id); | ||
576 | error_kfree: | ||
577 | kfree(mgr); | ||
578 | |||
579 | return NULL; | ||
580 | } | ||
581 | EXPORT_SYMBOL_GPL(fpga_mgr_create); | ||
582 | |||
583 | /** | ||
584 | * fpga_mgr_free - deallocate a FPGA manager | ||
585 | * @mgr: fpga manager struct created by fpga_mgr_create | ||
586 | */ | ||
587 | void fpga_mgr_free(struct fpga_manager *mgr) | ||
588 | { | ||
589 | ida_simple_remove(&fpga_mgr_ida, mgr->dev.id); | ||
590 | kfree(mgr); | ||
591 | } | ||
592 | EXPORT_SYMBOL_GPL(fpga_mgr_free); | ||
593 | |||
594 | /** | ||
595 | * fpga_mgr_register - register a FPGA manager | ||
596 | * @mgr: fpga manager struct created by fpga_mgr_create | ||
597 | * | ||
598 | * Return: 0 on success, negative error code otherwise. | ||
599 | */ | ||
600 | int fpga_mgr_register(struct fpga_manager *mgr) | ||
601 | { | ||
602 | int ret; | ||
603 | |||
604 | /* | ||
605 | * Initialize framework state by requesting low level driver read state | ||
606 | * from device. FPGA may be in reset mode or may have been programmed | ||
607 | * by bootloader or EEPROM. | ||
608 | */ | ||
609 | mgr->state = mgr->mops->state(mgr); | ||
610 | |||
580 | ret = device_add(&mgr->dev); | 611 | ret = device_add(&mgr->dev); |
581 | if (ret) | 612 | if (ret) |
582 | goto error_device; | 613 | goto error_device; |
@@ -586,22 +617,18 @@ int fpga_mgr_register(struct device *dev, const char *name, | |||
586 | return 0; | 617 | return 0; |
587 | 618 | ||
588 | error_device: | 619 | error_device: |
589 | ida_simple_remove(&fpga_mgr_ida, id); | 620 | ida_simple_remove(&fpga_mgr_ida, mgr->dev.id); |
590 | error_kfree: | ||
591 | kfree(mgr); | ||
592 | 621 | ||
593 | return ret; | 622 | return ret; |
594 | } | 623 | } |
595 | EXPORT_SYMBOL_GPL(fpga_mgr_register); | 624 | EXPORT_SYMBOL_GPL(fpga_mgr_register); |
596 | 625 | ||
597 | /** | 626 | /** |
598 | * fpga_mgr_unregister - unregister a low level fpga manager driver | 627 | * fpga_mgr_unregister - unregister a FPGA manager |
599 | * @dev: fpga manager device from pdev | 628 | * @mgr: fpga manager struct |
600 | */ | 629 | */ |
601 | void fpga_mgr_unregister(struct device *dev) | 630 | void fpga_mgr_unregister(struct fpga_manager *mgr) |
602 | { | 631 | { |
603 | struct fpga_manager *mgr = dev_get_drvdata(dev); | ||
604 | |||
605 | dev_info(&mgr->dev, "%s %s\n", __func__, mgr->name); | 632 | dev_info(&mgr->dev, "%s %s\n", __func__, mgr->name); |
606 | 633 | ||
607 | /* | 634 | /* |
@@ -619,8 +646,7 @@ static void fpga_mgr_dev_release(struct device *dev) | |||
619 | { | 646 | { |
620 | struct fpga_manager *mgr = to_fpga_manager(dev); | 647 | struct fpga_manager *mgr = to_fpga_manager(dev); |
621 | 648 | ||
622 | ida_simple_remove(&fpga_mgr_ida, mgr->dev.id); | 649 | fpga_mgr_free(mgr); |
623 | kfree(mgr); | ||
624 | } | 650 | } |
625 | 651 | ||
626 | static int __init fpga_mgr_class_init(void) | 652 | static int __init fpga_mgr_class_init(void) |