aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga/fpga-mgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/fpga/fpga-mgr.c')
-rw-r--r--drivers/fpga/fpga-mgr.c78
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)
515EXPORT_SYMBOL_GPL(fpga_mgr_unlock); 515EXPORT_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 */
526int fpga_mgr_register(struct device *dev, const char *name, 526struct 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
574error_device:
575 ida_simple_remove(&fpga_mgr_ida, id);
576error_kfree:
577 kfree(mgr);
578
579 return NULL;
580}
581EXPORT_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 */
587void fpga_mgr_free(struct fpga_manager *mgr)
588{
589 ida_simple_remove(&fpga_mgr_ida, mgr->dev.id);
590 kfree(mgr);
591}
592EXPORT_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 */
600int 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
588error_device: 619error_device:
589 ida_simple_remove(&fpga_mgr_ida, id); 620 ida_simple_remove(&fpga_mgr_ida, mgr->dev.id);
590error_kfree:
591 kfree(mgr);
592 621
593 return ret; 622 return ret;
594} 623}
595EXPORT_SYMBOL_GPL(fpga_mgr_register); 624EXPORT_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 */
601void fpga_mgr_unregister(struct device *dev) 630void 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
626static int __init fpga_mgr_class_init(void) 652static int __init fpga_mgr_class_init(void)