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

PM / AVS: SmartReflex: use devm_* API to initialize SmartReflex

Use of of devm_* API for resource allocation provides benefits such
as auto handling of resource free. This reduces possibility have
memory leaks in case of wrong error handling. All direct release
calls should be removed to avoid races.

Reported-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Andrii Tseglytskyi <andrii.tseglytskyi@ti.com>
Signed-off-by: Kevin Hilman <khilman@linaro.org>

authored by

Andrii Tseglytskyi and committed by
Kevin Hilman
efca406b 299066bb

+21 -55
+21 -55
drivers/power/avs/smartreflex.c
··· 28 28 #include <linux/power/smartreflex.h> 29 29 30 30 #define DRIVER_NAME "smartreflex" 31 - #define SMARTREFLEX_NAME_LEN 16 31 + #define SMARTREFLEX_NAME_LEN 32 32 32 #define NVALUE_NAME_LEN 40 33 33 #define SR_DISABLE_TIMEOUT 200 34 34 ··· 208 208 static int sr_late_init(struct omap_sr *sr_info) 209 209 { 210 210 struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data; 211 - struct resource *mem; 212 211 int ret = 0; 213 212 214 213 if (sr_class->notify && sr_class->notify_flags && sr_info->irq) { 215 - ret = request_irq(sr_info->irq, sr_interrupt, 216 - 0, sr_info->name, sr_info); 214 + ret = devm_request_irq(&sr_info->pdev->dev, sr_info->irq, 215 + sr_interrupt, 0, sr_info->name, sr_info); 217 216 if (ret) 218 217 goto error; 219 218 disable_irq(sr_info->irq); ··· 224 225 return ret; 225 226 226 227 error: 227 - iounmap(sr_info->base); 228 - mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0); 229 - release_mem_region(mem->start, resource_size(mem)); 230 228 list_del(&sr_info->node); 231 229 dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" 232 230 "interrupt handler. Smartreflex will" 233 231 "not function as desired\n", __func__); 234 - kfree(sr_info); 235 232 236 233 return ret; 237 234 } ··· 847 852 struct dentry *nvalue_dir; 848 853 int i, ret = 0; 849 854 850 - sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); 855 + sr_info = devm_kzalloc(&pdev->dev, sizeof(struct omap_sr), GFP_KERNEL); 851 856 if (!sr_info) { 852 857 dev_err(&pdev->dev, "%s: unable to allocate sr_info\n", 858 + __func__); 859 + return -ENOMEM; 860 + } 861 + 862 + sr_info->name = devm_kzalloc(&pdev->dev, 863 + SMARTREFLEX_NAME_LEN, GFP_KERNEL); 864 + if (!sr_info->name) { 865 + dev_err(&pdev->dev, "%s: unable to allocate SR instance name\n", 853 866 __func__); 854 867 return -ENOMEM; 855 868 } ··· 866 863 867 864 if (!pdata) { 868 865 dev_err(&pdev->dev, "%s: platform data missing\n", __func__); 869 - ret = -EINVAL; 870 - goto err_free_devinfo; 866 + return -EINVAL; 871 867 } 872 868 873 869 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 874 - if (!mem) { 875 - dev_err(&pdev->dev, "%s: no mem resource\n", __func__); 876 - ret = -ENODEV; 877 - goto err_free_devinfo; 878 - } 879 - 880 - mem = request_mem_region(mem->start, resource_size(mem), 881 - dev_name(&pdev->dev)); 882 - if (!mem) { 883 - dev_err(&pdev->dev, "%s: no mem region\n", __func__); 884 - ret = -EBUSY; 885 - goto err_free_devinfo; 870 + sr_info->base = devm_ioremap_resource(&pdev->dev, mem); 871 + if (IS_ERR(sr_info->base)) { 872 + dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); 873 + return PTR_ERR(sr_info->base); 886 874 } 887 875 888 876 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ··· 881 887 pm_runtime_enable(&pdev->dev); 882 888 pm_runtime_irq_safe(&pdev->dev); 883 889 884 - sr_info->name = kasprintf(GFP_KERNEL, "%s", pdata->name); 885 - if (!sr_info->name) { 886 - dev_err(&pdev->dev, "%s: Unable to alloc SR instance name\n", 887 - __func__); 888 - ret = -ENOMEM; 889 - goto err_release_region; 890 - } 890 + snprintf(sr_info->name, SMARTREFLEX_NAME_LEN, "%s", pdata->name); 891 891 892 892 sr_info->pdev = pdev; 893 893 sr_info->srid = pdev->id; ··· 898 910 sr_info->autocomp_active = false; 899 911 sr_info->ip_type = pdata->ip_type; 900 912 901 - sr_info->base = ioremap(mem->start, resource_size(mem)); 902 - if (!sr_info->base) { 903 - dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); 904 - ret = -ENOMEM; 905 - goto err_free_name; 906 - } 907 - 908 913 if (irq) 909 914 sr_info->irq = irq->start; 910 915 ··· 913 932 ret = sr_late_init(sr_info); 914 933 if (ret) { 915 934 pr_warning("%s: Error in SR late init\n", __func__); 916 - goto err_iounmap; 935 + goto err_list_del; 917 936 } 918 937 } 919 938 ··· 924 943 ret = PTR_ERR(sr_dbg_dir); 925 944 pr_err("%s:sr debugfs dir creation failed(%d)\n", 926 945 __func__, ret); 927 - goto err_iounmap; 946 + goto err_list_del; 928 947 } 929 948 } 930 949 ··· 977 996 978 997 err_debugfs: 979 998 debugfs_remove_recursive(sr_info->dbg_dir); 980 - err_iounmap: 999 + err_list_del: 981 1000 list_del(&sr_info->node); 982 - iounmap(sr_info->base); 983 - err_free_name: 984 - kfree(sr_info->name); 985 - err_release_region: 986 - release_mem_region(mem->start, resource_size(mem)); 987 - err_free_devinfo: 988 - kfree(sr_info); 989 - 990 1001 return ret; 991 1002 } 992 1003 ··· 986 1013 { 987 1014 struct omap_sr_data *pdata = pdev->dev.platform_data; 988 1015 struct omap_sr *sr_info; 989 - struct resource *mem; 990 1016 991 1017 if (!pdata) { 992 1018 dev_err(&pdev->dev, "%s: platform data missing\n", __func__); ··· 1006 1034 1007 1035 pm_runtime_disable(&pdev->dev); 1008 1036 list_del(&sr_info->node); 1009 - iounmap(sr_info->base); 1010 - kfree(sr_info->name); 1011 - kfree(sr_info); 1012 - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1013 - release_mem_region(mem->start, resource_size(mem)); 1014 - 1015 1037 return 0; 1016 1038 } 1017 1039