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.stras...@ti.com
Signed-off-by: Andrii Tseglytskyi andrii.tseglyts...@ti.com
---
drivers/power/avs/smartreflex.c | 76 +++
1 file changed, 21 insertions(+), 55 deletions(-)
diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c
index 6b2238b..fd71d5a 100644
--- a/drivers/power/avs/smartreflex.c
+++ b/drivers/power/avs/smartreflex.c
@@ -27,7 +27,7 @@
#include linux/pm_runtime.h
#include linux/power/smartreflex.h
-#define SMARTREFLEX_NAME_LEN 16
+#define SMARTREFLEX_NAME_LEN 32
#define NVALUE_NAME_LEN40
#define SR_DISABLE_TIMEOUT 200
@@ -207,12 +207,11 @@ static void sr_stop_vddautocomp(struct omap_sr *sr)
static int sr_late_init(struct omap_sr *sr_info)
{
struct omap_sr_data *pdata = sr_info-pdev-dev.platform_data;
- struct resource *mem;
int ret = 0;
if (sr_class-notify sr_class-notify_flags sr_info-irq) {
- ret = request_irq(sr_info-irq, sr_interrupt,
- 0, sr_info-name, sr_info);
+ ret = devm_request_irq(sr_info-pdev-dev, sr_info-irq,
+ sr_interrupt, 0, sr_info-name, sr_info);
if (ret)
goto error;
disable_irq(sr_info-irq);
@@ -224,14 +223,10 @@ static int sr_late_init(struct omap_sr *sr_info)
return ret;
error:
- iounmap(sr_info-base);
- mem = platform_get_resource(sr_info-pdev, IORESOURCE_MEM, 0);
- release_mem_region(mem-start, resource_size(mem));
list_del(sr_info-node);
dev_err(sr_info-pdev-dev, %s: ERROR in registering
interrupt handler. Smartreflex will
not function as desired\n, __func__);
- kfree(sr_info);
return ret;
}
@@ -847,34 +842,33 @@ static int __init omap_sr_probe(struct platform_device
*pdev)
struct dentry *nvalue_dir;
int i, ret = 0;
- sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
+ sr_info = devm_kzalloc(pdev-dev, sizeof(struct omap_sr), GFP_KERNEL);
if (!sr_info) {
dev_err(pdev-dev, %s: unable to allocate sr_info\n,
__func__);
return -ENOMEM;
}
+ sr_info-name = devm_kzalloc(pdev-dev,
+SMARTREFLEX_NAME_LEN, GFP_KERNEL);
+ if (!sr_info-name) {
+ dev_err(pdev-dev, %s: unable to allocate SR instance name\n,
+ __func__);
+ return -ENOMEM;
+ }
+
platform_set_drvdata(pdev, sr_info);
if (!pdata) {
dev_err(pdev-dev, %s: platform data missing\n, __func__);
- ret = -EINVAL;
- goto err_free_devinfo;
+ return -EINVAL;
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(pdev-dev, %s: no mem resource\n, __func__);
- ret = -ENODEV;
- goto err_free_devinfo;
- }
-
- mem = request_mem_region(mem-start, resource_size(mem),
- dev_name(pdev-dev));
- if (!mem) {
- dev_err(pdev-dev, %s: no mem region\n, __func__);
- ret = -EBUSY;
- goto err_free_devinfo;
+ sr_info-base = devm_ioremap_resource(pdev-dev, mem);
+ if (IS_ERR(sr_info-base)) {
+ dev_err(pdev-dev, %s: ioremap fail\n, __func__);
+ return PTR_ERR(sr_info-base);
}
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -882,13 +876,7 @@ static int __init omap_sr_probe(struct platform_device
*pdev)
pm_runtime_enable(pdev-dev);
pm_runtime_irq_safe(pdev-dev);
- sr_info-name = kasprintf(GFP_KERNEL, %s, pdata-name);
- if (!sr_info-name) {
- dev_err(pdev-dev, %s: Unable to alloc SR instance name\n,
- __func__);
- ret = -ENOMEM;
- goto err_release_region;
- }
+ snprintf(sr_info-name, SMARTREFLEX_NAME_LEN, %s, pdata-name);
sr_info-pdev = pdev;
sr_info-srid = pdev-id;
@@ -905,13 +893,6 @@ static int __init omap_sr_probe(struct platform_device
*pdev)
sr_info-autocomp_active = false;
sr_info-ip_type = pdata-ip_type;
- sr_info-base = ioremap(mem-start, resource_size(mem));
- if (!sr_info-base) {
- dev_err(pdev-dev, %s: ioremap fail\n, __func__);
- ret = -ENOMEM;
- goto err_free_name;
- }
-
if (irq)
sr_info-irq = irq-start;
@@ -927,7 +908,7 @@ static int