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

staging: most: dim2: use device release method

Commit 723de0f9171e ("staging: most: remove device from interface
structure") moved registration of driver-provided struct device to
the most subsystem. This updated dim2 driver as well.

However, struct device passed to register_device() becomes refcounted,
and must not be explicitly deallocated, but must provide release method
instead. Which is incompatible with managing it via devres.

This patch makes the device structure allocated without devres, adds
device release method, and moves device destruction there.

Fixes: 723de0f9171e ("staging: most: remove device from interface structure")
Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Link: https://lore.kernel.org/r/20211005143448.8660-2-nikita.yoush@cogentembedded.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Nikita Yushchenko and committed by
Greg Kroah-Hartman
d445aa40 2ab18916

+30 -25
+30 -25
drivers/staging/most/dim2/dim2.c
··· 727 727 return -EINVAL; 728 728 } 729 729 730 + static void dim2_release(struct device *d) 731 + { 732 + struct dim2_hdm *dev = container_of(d, struct dim2_hdm, dev); 733 + unsigned long flags; 734 + 735 + kthread_stop(dev->netinfo_task); 736 + 737 + spin_lock_irqsave(&dim_lock, flags); 738 + dim_shutdown(); 739 + spin_unlock_irqrestore(&dim_lock, flags); 740 + 741 + if (dev->disable_platform) 742 + dev->disable_platform(to_platform_device(d->parent)); 743 + 744 + kfree(dev); 745 + } 746 + 730 747 /* 731 748 * dim2_probe - dim2 probe handler 732 749 * @pdev: platform device structure ··· 765 748 766 749 enum { MLB_INT_IDX, AHB0_INT_IDX }; 767 750 768 - dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); 751 + dev = kzalloc(sizeof(*dev), GFP_KERNEL); 769 752 if (!dev) 770 753 return -ENOMEM; 771 754 ··· 777 760 "microchip,clock-speed", &clock_speed); 778 761 if (ret) { 779 762 dev_err(&pdev->dev, "missing dt property clock-speed\n"); 780 - return ret; 763 + goto err_free_dev; 781 764 } 782 765 783 766 ret = get_dim2_clk_speed(clock_speed, &dev->clk_speed); 784 767 if (ret) { 785 768 dev_err(&pdev->dev, "bad dt property clock-speed\n"); 786 - return ret; 769 + goto err_free_dev; 787 770 } 788 771 789 772 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 790 773 dev->io_base = devm_ioremap_resource(&pdev->dev, res); 791 - if (IS_ERR(dev->io_base)) 792 - return PTR_ERR(dev->io_base); 774 + if (IS_ERR(dev->io_base)) { 775 + ret = PTR_ERR(dev->io_base); 776 + goto err_free_dev; 777 + } 793 778 794 779 of_id = of_match_node(dim2_of_match, pdev->dev.of_node); 795 780 pdata = of_id->data; ··· 799 780 if (pdata->enable) { 800 781 ret = pdata->enable(pdev); 801 782 if (ret) 802 - return ret; 783 + goto err_free_dev; 803 784 } 804 785 dev->disable_platform = pdata->disable; 805 786 if (pdata->fcnt) ··· 894 875 dev->most_iface.request_netinfo = request_netinfo; 895 876 dev->most_iface.driver_dev = &pdev->dev; 896 877 dev->most_iface.dev = &dev->dev; 897 - dev->dev.init_name = "dim2_state"; 878 + dev->dev.init_name = dev->name; 898 879 dev->dev.parent = &pdev->dev; 880 + dev->dev.release = dim2_release; 899 881 900 - ret = most_register_interface(&dev->most_iface); 901 - if (ret) { 902 - dev_err(&pdev->dev, "failed to register MOST interface\n"); 903 - goto err_stop_thread; 904 - } 882 + return most_register_interface(&dev->most_iface); 905 883 906 - return 0; 907 - 908 - err_stop_thread: 909 - kthread_stop(dev->netinfo_task); 910 884 err_shutdown_dim: 911 885 dim_shutdown(); 912 886 err_disable_platform: 913 887 if (dev->disable_platform) 914 888 dev->disable_platform(pdev); 889 + err_free_dev: 890 + kfree(dev); 915 891 916 892 return ret; 917 893 } ··· 920 906 static int dim2_remove(struct platform_device *pdev) 921 907 { 922 908 struct dim2_hdm *dev = platform_get_drvdata(pdev); 923 - unsigned long flags; 924 909 925 910 most_deregister_interface(&dev->most_iface); 926 - kthread_stop(dev->netinfo_task); 927 - 928 - spin_lock_irqsave(&dim_lock, flags); 929 - dim_shutdown(); 930 - spin_unlock_irqrestore(&dim_lock, flags); 931 - 932 - if (dev->disable_platform) 933 - dev->disable_platform(pdev); 934 911 935 912 return 0; 936 913 }