Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

char: xilinx_hwicap: Modernize driver probe

Rework Xilinx hwicap driver probe to use current best practices using
devres APIs, device_get_match_data(), and typed firmware property accessors.

There's no longer any non-DT probing, so CONFIG_OF ifdefs can be dropped.

Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20231006214228.337064-1-robh@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Rob Herring and committed by
Greg Kroah-Hartman
67237183 066eaa69

+19 -119
+19 -119
drivers/char/xilinx_hwicap/xilinx_hwicap.c
··· 84 84 #include <linux/sysctl.h> 85 85 #include <linux/fs.h> 86 86 #include <linux/cdev.h> 87 + #include <linux/of.h> 87 88 #include <linux/platform_device.h> 89 + #include <linux/property.h> 88 90 #include <linux/slab.h> 89 91 #include <linux/io.h> 90 92 #include <linux/uaccess.h> 91 - 92 - #ifdef CONFIG_OF 93 - /* For open firmware. */ 94 - #include <linux/of_address.h> 95 - #include <linux/of_device.h> 96 - #include <linux/of_platform.h> 97 - #endif 98 93 99 94 #include "xilinx_hwicap.h" 100 95 #include "buffer_icap.h" ··· 596 601 .llseek = noop_llseek, 597 602 }; 598 603 599 - static int hwicap_setup(struct device *dev, int id, 600 - const struct resource *regs_res, 604 + static int hwicap_setup(struct platform_device *pdev, int id, 601 605 const struct hwicap_driver_config *config, 602 606 const struct config_registers *config_regs) 603 607 { 604 608 dev_t devt; 605 609 struct hwicap_drvdata *drvdata = NULL; 606 - int retval = 0; 610 + struct device *dev = &pdev->dev; 611 + int retval; 607 612 608 613 dev_info(dev, "Xilinx icap port driver\n"); 609 614 ··· 631 636 632 637 devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR + id); 633 638 634 - drvdata = kzalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL); 639 + drvdata = devm_kzalloc(dev, sizeof(struct hwicap_drvdata), GFP_KERNEL); 635 640 if (!drvdata) { 636 641 retval = -ENOMEM; 637 - goto failed0; 642 + goto failed; 638 643 } 639 644 dev_set_drvdata(dev, (void *)drvdata); 640 645 641 - if (!regs_res) { 642 - dev_err(dev, "Couldn't get registers resource\n"); 643 - retval = -EFAULT; 644 - goto failed1; 645 - } 646 - 647 - drvdata->mem_start = regs_res->start; 648 - drvdata->mem_end = regs_res->end; 649 - drvdata->mem_size = resource_size(regs_res); 650 - 651 - if (!request_mem_region(drvdata->mem_start, 652 - drvdata->mem_size, DRIVER_NAME)) { 653 - dev_err(dev, "Couldn't lock memory region at %Lx\n", 654 - (unsigned long long) regs_res->start); 655 - retval = -EBUSY; 656 - goto failed1; 646 + drvdata->base_address = devm_platform_ioremap_resource(pdev, 0); 647 + if (!drvdata->base_address) { 648 + retval = -ENODEV; 649 + goto failed; 657 650 } 658 651 659 652 drvdata->devt = devt; 660 653 drvdata->dev = dev; 661 - drvdata->base_address = ioremap(drvdata->mem_start, drvdata->mem_size); 662 - if (!drvdata->base_address) { 663 - dev_err(dev, "ioremap() failed\n"); 664 - retval = -ENOMEM; 665 - goto failed2; 666 - } 667 - 668 654 drvdata->config = config; 669 655 drvdata->config_regs = config_regs; 670 656 671 657 mutex_init(&drvdata->sem); 672 658 drvdata->is_open = 0; 673 659 674 - dev_info(dev, "ioremap %llx to %p with size %llx\n", 675 - (unsigned long long) drvdata->mem_start, 676 - drvdata->base_address, 677 - (unsigned long long) drvdata->mem_size); 678 - 679 660 cdev_init(&drvdata->cdev, &hwicap_fops); 680 661 drvdata->cdev.owner = THIS_MODULE; 681 662 retval = cdev_add(&drvdata->cdev, devt, 1); 682 663 if (retval) { 683 664 dev_err(dev, "cdev_add() failed\n"); 684 - goto failed3; 665 + goto failed; 685 666 } 686 667 687 668 device_create(&icap_class, dev, devt, NULL, "%s%d", DRIVER_NAME, id); 688 669 return 0; /* success */ 689 670 690 - failed3: 691 - iounmap(drvdata->base_address); 692 - 693 - failed2: 694 - release_mem_region(regs_res->start, drvdata->mem_size); 695 - 696 - failed1: 697 - kfree(drvdata); 698 - 699 - failed0: 671 + failed: 700 672 mutex_lock(&icap_sem); 701 673 probed_devices[id] = 0; 702 674 mutex_unlock(&icap_sem); ··· 685 723 .reset = fifo_icap_reset, 686 724 }; 687 725 688 - #ifdef CONFIG_OF 689 - static int hwicap_of_probe(struct platform_device *op, 690 - const struct hwicap_driver_config *config) 691 - { 692 - struct resource res; 693 - const unsigned int *id; 694 - const char *family; 695 - int rc; 696 - const struct config_registers *regs; 697 - 698 - 699 - rc = of_address_to_resource(op->dev.of_node, 0, &res); 700 - if (rc) { 701 - dev_err(&op->dev, "invalid address\n"); 702 - return rc; 703 - } 704 - 705 - id = of_get_property(op->dev.of_node, "port-number", NULL); 706 - 707 - /* It's most likely that we're using V4, if the family is not 708 - * specified 709 - */ 710 - regs = &v4_config_registers; 711 - family = of_get_property(op->dev.of_node, "xlnx,family", NULL); 712 - 713 - if (family) { 714 - if (!strcmp(family, "virtex2p")) 715 - regs = &v2_config_registers; 716 - else if (!strcmp(family, "virtex4")) 717 - regs = &v4_config_registers; 718 - else if (!strcmp(family, "virtex5")) 719 - regs = &v5_config_registers; 720 - else if (!strcmp(family, "virtex6")) 721 - regs = &v6_config_registers; 722 - } 723 - return hwicap_setup(&op->dev, id ? *id : -1, &res, config, 724 - regs); 725 - } 726 - #else 727 - static inline int hwicap_of_probe(struct platform_device *op, 728 - const struct hwicap_driver_config *config) 729 - { 730 - return -EINVAL; 731 - } 732 - #endif /* CONFIG_OF */ 733 - 734 - static const struct of_device_id hwicap_of_match[]; 735 726 static int hwicap_drv_probe(struct platform_device *pdev) 736 727 { 737 - const struct of_device_id *match; 738 - struct resource *res; 739 728 const struct config_registers *regs; 729 + const struct hwicap_driver_config *config; 740 730 const char *family; 731 + int id = -1; 741 732 742 - match = of_match_device(hwicap_of_match, &pdev->dev); 743 - if (match) 744 - return hwicap_of_probe(pdev, match->data); 733 + config = device_get_match_data(&pdev->dev); 745 734 746 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 747 - if (!res) 748 - return -ENODEV; 735 + of_property_read_u32(pdev->dev.of_node, "port-number", &id); 749 736 750 737 /* It's most likely that we're using V4, if the family is not 751 738 * specified 752 739 */ 753 740 regs = &v4_config_registers; 754 - family = pdev->dev.platform_data; 755 - 756 - if (family) { 741 + if (!of_property_read_string(pdev->dev.of_node, "xlnx,family", &family)) { 757 742 if (!strcmp(family, "virtex2p")) 758 743 regs = &v2_config_registers; 759 744 else if (!strcmp(family, "virtex4")) ··· 710 801 else if (!strcmp(family, "virtex6")) 711 802 regs = &v6_config_registers; 712 803 } 713 - 714 - return hwicap_setup(&pdev->dev, pdev->id, res, 715 - &buffer_icap_config, regs); 804 + return hwicap_setup(pdev, id, config, regs); 716 805 } 717 806 718 807 static void hwicap_drv_remove(struct platform_device *pdev) ··· 722 815 723 816 device_destroy(&icap_class, drvdata->devt); 724 817 cdev_del(&drvdata->cdev); 725 - iounmap(drvdata->base_address); 726 - release_mem_region(drvdata->mem_start, drvdata->mem_size); 727 - kfree(drvdata); 728 818 729 819 mutex_lock(&icap_sem); 730 820 probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0; 731 821 mutex_unlock(&icap_sem); 732 822 } 733 823 734 - #ifdef CONFIG_OF 735 824 /* Match table for device tree binding */ 736 825 static const struct of_device_id hwicap_of_match[] = { 737 826 { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config}, ··· 735 832 {}, 736 833 }; 737 834 MODULE_DEVICE_TABLE(of, hwicap_of_match); 738 - #else 739 - #define hwicap_of_match NULL 740 - #endif 741 835 742 836 static struct platform_driver hwicap_platform_driver = { 743 837 .probe = hwicap_drv_probe,