aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/avs
diff options
context:
space:
mode:
authorAndrii Tseglytskyi <andrii.tseglytskyi@ti.com>2013-05-30 06:43:56 -0400
committerKevin Hilman <khilman@linaro.org>2013-06-10 13:50:48 -0400
commitefca406b940e93e6af38c597eecd5fb79b39b7ea (patch)
treee574cadaf5887baaa7e1a49ce555601ea806fe76 /drivers/power/avs
parent299066bb376ef7720cc3d8de95d5b967c5446863 (diff)
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>
Diffstat (limited to 'drivers/power/avs')
-rw-r--r--drivers/power/avs/smartreflex.c76
1 files changed, 21 insertions, 55 deletions
diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c
index 14cce7addbb9..db9973bb53f1 100644
--- a/drivers/power/avs/smartreflex.c
+++ b/drivers/power/avs/smartreflex.c
@@ -28,7 +28,7 @@
28#include <linux/power/smartreflex.h> 28#include <linux/power/smartreflex.h>
29 29
30#define DRIVER_NAME "smartreflex" 30#define DRIVER_NAME "smartreflex"
31#define SMARTREFLEX_NAME_LEN 16 31#define SMARTREFLEX_NAME_LEN 32
32#define NVALUE_NAME_LEN 40 32#define NVALUE_NAME_LEN 40
33#define SR_DISABLE_TIMEOUT 200 33#define SR_DISABLE_TIMEOUT 200
34 34
@@ -208,12 +208,11 @@ static void sr_stop_vddautocomp(struct omap_sr *sr)
208static int sr_late_init(struct omap_sr *sr_info) 208static int sr_late_init(struct omap_sr *sr_info)
209{ 209{
210 struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data; 210 struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data;
211 struct resource *mem;
212 int ret = 0; 211 int ret = 0;
213 212
214 if (sr_class->notify && sr_class->notify_flags && sr_info->irq) { 213 if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
215 ret = request_irq(sr_info->irq, sr_interrupt, 214 ret = devm_request_irq(&sr_info->pdev->dev, sr_info->irq,
216 0, sr_info->name, sr_info); 215 sr_interrupt, 0, sr_info->name, sr_info);
217 if (ret) 216 if (ret)
218 goto error; 217 goto error;
219 disable_irq(sr_info->irq); 218 disable_irq(sr_info->irq);
@@ -225,14 +224,10 @@ static int sr_late_init(struct omap_sr *sr_info)
225 return ret; 224 return ret;
226 225
227error: 226error:
228 iounmap(sr_info->base);
229 mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
230 release_mem_region(mem->start, resource_size(mem));
231 list_del(&sr_info->node); 227 list_del(&sr_info->node);
232 dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" 228 dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
233 "interrupt handler. Smartreflex will" 229 "interrupt handler. Smartreflex will"
234 "not function as desired\n", __func__); 230 "not function as desired\n", __func__);
235 kfree(sr_info);
236 231
237 return ret; 232 return ret;
238} 233}
@@ -852,34 +847,33 @@ static int __init omap_sr_probe(struct platform_device *pdev)
852 struct dentry *nvalue_dir; 847 struct dentry *nvalue_dir;
853 int i, ret = 0; 848 int i, ret = 0;
854 849
855 sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); 850 sr_info = devm_kzalloc(&pdev->dev, sizeof(struct omap_sr), GFP_KERNEL);
856 if (!sr_info) { 851 if (!sr_info) {
857 dev_err(&pdev->dev, "%s: unable to allocate sr_info\n", 852 dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
858 __func__); 853 __func__);
859 return -ENOMEM; 854 return -ENOMEM;
860 } 855 }
861 856
857 sr_info->name = devm_kzalloc(&pdev->dev,
858 SMARTREFLEX_NAME_LEN, GFP_KERNEL);
859 if (!sr_info->name) {
860 dev_err(&pdev->dev, "%s: unable to allocate SR instance name\n",
861 __func__);
862 return -ENOMEM;
863 }
864
862 platform_set_drvdata(pdev, sr_info); 865 platform_set_drvdata(pdev, sr_info);
863 866
864 if (!pdata) { 867 if (!pdata) {
865 dev_err(&pdev->dev, "%s: platform data missing\n", __func__); 868 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
866 ret = -EINVAL; 869 return -EINVAL;
867 goto err_free_devinfo;
868 } 870 }
869 871
870 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 872 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
871 if (!mem) { 873 sr_info->base = devm_ioremap_resource(&pdev->dev, mem);
872 dev_err(&pdev->dev, "%s: no mem resource\n", __func__); 874 if (IS_ERR(sr_info->base)) {
873 ret = -ENODEV; 875 dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
874 goto err_free_devinfo; 876 return PTR_ERR(sr_info->base);
875 }
876
877 mem = request_mem_region(mem->start, resource_size(mem),
878 dev_name(&pdev->dev));
879 if (!mem) {
880 dev_err(&pdev->dev, "%s: no mem region\n", __func__);
881 ret = -EBUSY;
882 goto err_free_devinfo;
883 } 877 }
884 878
885 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 879 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -887,13 +881,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
887 pm_runtime_enable(&pdev->dev); 881 pm_runtime_enable(&pdev->dev);
888 pm_runtime_irq_safe(&pdev->dev); 882 pm_runtime_irq_safe(&pdev->dev);
889 883
890 sr_info->name = kasprintf(GFP_KERNEL, "%s", pdata->name); 884 snprintf(sr_info->name, SMARTREFLEX_NAME_LEN, "%s", pdata->name);
891 if (!sr_info->name) {
892 dev_err(&pdev->dev, "%s: Unable to alloc SR instance name\n",
893 __func__);
894 ret = -ENOMEM;
895 goto err_release_region;
896 }
897 885
898 sr_info->pdev = pdev; 886 sr_info->pdev = pdev;
899 sr_info->srid = pdev->id; 887 sr_info->srid = pdev->id;
@@ -910,13 +898,6 @@ static int __init omap_sr_probe(struct platform_device *pdev)
910 sr_info->autocomp_active = false; 898 sr_info->autocomp_active = false;
911 sr_info->ip_type = pdata->ip_type; 899 sr_info->ip_type = pdata->ip_type;
912 900
913 sr_info->base = ioremap(mem->start, resource_size(mem));
914 if (!sr_info->base) {
915 dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
916 ret = -ENOMEM;
917 goto err_free_name;
918 }
919
920 if (irq) 901 if (irq)
921 sr_info->irq = irq->start; 902 sr_info->irq = irq->start;
922 903
@@ -932,7 +913,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
932 ret = sr_late_init(sr_info); 913 ret = sr_late_init(sr_info);
933 if (ret) { 914 if (ret) {
934 pr_warning("%s: Error in SR late init\n", __func__); 915 pr_warning("%s: Error in SR late init\n", __func__);
935 goto err_iounmap; 916 goto err_list_del;
936 } 917 }
937 } 918 }
938 919
@@ -943,7 +924,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
943 ret = PTR_ERR(sr_dbg_dir); 924 ret = PTR_ERR(sr_dbg_dir);
944 pr_err("%s:sr debugfs dir creation failed(%d)\n", 925 pr_err("%s:sr debugfs dir creation failed(%d)\n",
945 __func__, ret); 926 __func__, ret);
946 goto err_iounmap; 927 goto err_list_del;
947 } 928 }
948 } 929 }
949 930
@@ -996,16 +977,8 @@ static int __init omap_sr_probe(struct platform_device *pdev)
996 977
997err_debugfs: 978err_debugfs:
998 debugfs_remove_recursive(sr_info->dbg_dir); 979 debugfs_remove_recursive(sr_info->dbg_dir);
999err_iounmap: 980err_list_del:
1000 list_del(&sr_info->node); 981 list_del(&sr_info->node);
1001 iounmap(sr_info->base);
1002err_free_name:
1003 kfree(sr_info->name);
1004err_release_region:
1005 release_mem_region(mem->start, resource_size(mem));
1006err_free_devinfo:
1007 kfree(sr_info);
1008
1009 return ret; 982 return ret;
1010} 983}
1011 984
@@ -1013,7 +986,6 @@ static int omap_sr_remove(struct platform_device *pdev)
1013{ 986{
1014 struct omap_sr_data *pdata = pdev->dev.platform_data; 987 struct omap_sr_data *pdata = pdev->dev.platform_data;
1015 struct omap_sr *sr_info; 988 struct omap_sr *sr_info;
1016 struct resource *mem;
1017 989
1018 if (!pdata) { 990 if (!pdata) {
1019 dev_err(&pdev->dev, "%s: platform data missing\n", __func__); 991 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
@@ -1034,12 +1006,6 @@ static int omap_sr_remove(struct platform_device *pdev)
1034 1006
1035 pm_runtime_disable(&pdev->dev); 1007 pm_runtime_disable(&pdev->dev);
1036 list_del(&sr_info->node); 1008 list_del(&sr_info->node);
1037 iounmap(sr_info->base);
1038 kfree(sr_info->name);
1039 kfree(sr_info);
1040 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1041 release_mem_region(mem->start, resource_size(mem));
1042
1043 return 0; 1009 return 0;
1044} 1010}
1045 1011