From 824ead03b78403a21449cb7eb153a4344cd3b4c8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 8 Oct 2015 14:34:02 +0900 Subject: thermal: exynos: Fix unbalanced regulator disable on probe failure During probe if the regulator could not be enabled, the error exit path would still disable it. This could lead to unbalanced counter of regulator enable/disable. The patch moves code for getting and enabling the regulator from exynos_map_dt_data() to probe function because it is really not a part of getting Device Tree properties. Acked-by: Lukasz Majewski Tested-by: Lukasz Majewski Reviewed-by: Alim Akhtar Signed-off-by: Krzysztof Kozlowski Fixes: 5f09a5cbd14a ("thermal: exynos: Disable the regulator on probe failure") Cc: Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers/thermal/samsung') diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 0bae8cc6c23a..23f4320f8ef7 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -1168,27 +1168,10 @@ static int exynos_map_dt_data(struct platform_device *pdev) struct exynos_tmu_data *data = platform_get_drvdata(pdev); struct exynos_tmu_platform_data *pdata; struct resource res; - int ret; if (!data || !pdev->dev.of_node) return -ENODEV; - /* - * Try enabling the regulator if found - * TODO: Add regulator as an SOC feature, so that regulator enable - * is a compulsory call. - */ - data->regulator = devm_regulator_get(&pdev->dev, "vtmu"); - if (!IS_ERR(data->regulator)) { - ret = regulator_enable(data->regulator); - if (ret) { - dev_err(&pdev->dev, "failed to enable vtmu\n"); - return ret; - } - } else { - dev_info(&pdev->dev, "Regulator node (vtmu) not found\n"); - } - data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl"); if (data->id < 0) data->id = 0; @@ -1312,6 +1295,23 @@ static int exynos_tmu_probe(struct platform_device *pdev) pr_err("thermal: tz: %p ERROR\n", data->tzd); return PTR_ERR(data->tzd); } + + /* + * Try enabling the regulator if found + * TODO: Add regulator as an SOC feature, so that regulator enable + * is a compulsory call. + */ + data->regulator = devm_regulator_get(&pdev->dev, "vtmu"); + if (!IS_ERR(data->regulator)) { + ret = regulator_enable(data->regulator); + if (ret) { + dev_err(&pdev->dev, "failed to enable vtmu\n"); + return ret; + } + } else { + dev_info(&pdev->dev, "Regulator node (vtmu) not found\n"); + } + ret = exynos_map_dt_data(pdev); if (ret) goto err_sensor; -- cgit v1.2.3-59-g8ed1b From 9e4249b4034090730017deaf632b46b5faaa12b9 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 8 Oct 2015 14:34:03 +0900 Subject: thermal: exynos: Fix first temperature read after registering sensor Thermal core could not read the temperature after registering the thermal sensor with thermal_zone_of_sensor_register() because the driver was not yet initialized. The call trace looked like: exynos_tmu_probe() thermal_zone_of_sensor_register() of_thermal_set_mode() thermal_zone_device_update() exynos_get_temp() if (!data->tmu_read) return -EINVAL; exynos_map_dt_data() data->tmu_read = ... This produced an error in dmesg: thermal thermal_zone0: failed to read out thermal zone (-22) Register the thermal_zone_device later, after parsing Device Tree and enabling necessary clocks, but before calling exynos_tmu_initialize() which uses the registered thermal_zone_device. Reviewed-by: Alim Akhtar Tested-by: Alim Akhtar Acked-by: Lukasz Majewski Tested-by: Lukasz Majewski Signed-off-by: Krzysztof Kozlowski Fixes: 3b6a1a805f34 ("thermal: samsung: core: Exynos TMU rework to use device tree for configuration") Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers/thermal/samsung') diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 23f4320f8ef7..bc71a61f0c4a 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -1289,13 +1289,6 @@ static int exynos_tmu_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); mutex_init(&data->lock); - data->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, data, - &exynos_sensor_ops); - if (IS_ERR(data->tzd)) { - pr_err("thermal: tz: %p ERROR\n", data->tzd); - return PTR_ERR(data->tzd); - } - /* * Try enabling the regulator if found * TODO: Add regulator as an SOC feature, so that regulator enable @@ -1365,21 +1358,36 @@ static int exynos_tmu_probe(struct platform_device *pdev) break; }; + /* + * data->tzd must be registered before calling exynos_tmu_initialize(), + * requesting irq and calling exynos_tmu_control(). + */ + data->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, data, + &exynos_sensor_ops); + if (IS_ERR(data->tzd)) { + ret = PTR_ERR(data->tzd); + dev_err(&pdev->dev, "Failed to register sensor: %d\n", ret); + goto err_sclk; + } + ret = exynos_tmu_initialize(pdev); if (ret) { dev_err(&pdev->dev, "Failed to initialize TMU\n"); - goto err_sclk; + goto err_thermal; } ret = devm_request_irq(&pdev->dev, data->irq, exynos_tmu_irq, IRQF_TRIGGER_RISING | IRQF_SHARED, dev_name(&pdev->dev), data); if (ret) { dev_err(&pdev->dev, "Failed to request irq: %d\n", data->irq); - goto err_sclk; + goto err_thermal; } exynos_tmu_control(pdev, true); return 0; + +err_thermal: + thermal_zone_of_sensor_unregister(&pdev->dev, data->tzd); err_sclk: clk_disable_unprepare(data->sclk); err_clk: @@ -1390,7 +1398,6 @@ err_clk_sec: err_sensor: if (!IS_ERR_OR_NULL(data->regulator)) regulator_disable(data->regulator); - thermal_zone_of_sensor_unregister(&pdev->dev, data->tzd); return ret; } -- cgit v1.2.3-59-g8ed1b From bfa26838572cd9b2b0623fcbc7b9352dcaa4262b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 8 Oct 2015 14:34:04 +0900 Subject: thermal: exynos: Use IS_ERR() because regulator cannot be NULL The NULL check in probe's error path is not needed because in that time the regulator cannot be NULL (regulator_get() returns valid pointer or ERR_PTR). Reviewed-by: Alim Akhtar Acked-by: Lukasz Majewski Tested-by: Lukasz Majewski Signed-off-by: Krzysztof Kozlowski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/thermal/samsung') diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index bc71a61f0c4a..eac6aebf82f3 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -1396,7 +1396,7 @@ err_clk_sec: if (!IS_ERR(data->clk_sec)) clk_unprepare(data->clk_sec); err_sensor: - if (!IS_ERR_OR_NULL(data->regulator)) + if (!IS_ERR(data->regulator)) regulator_disable(data->regulator); return ret; -- cgit v1.2.3-59-g8ed1b From baba1ebb99ba1ffecfa40268d80e4e6406ef1d17 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 8 Oct 2015 14:34:05 +0900 Subject: thermal: exynos: Remove unneeded semicolon Remove semicolons after switch statement. Acked-by: Lukasz Majewski Tested-by: Lukasz Majewski Signed-off-by: Krzysztof Kozlowski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/thermal/samsung') diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index eac6aebf82f3..1af7ea8dda71 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -548,7 +548,7 @@ static int exynos5433_tmu_initialize(struct platform_device *pdev) default: pdata->cal_type = TYPE_ONE_POINT_TRIMMING; break; - }; + } dev_info(&pdev->dev, "Calibration type is %d-point calibration\n", cal_type ? 2 : 1); @@ -1356,7 +1356,7 @@ static int exynos_tmu_probe(struct platform_device *pdev) break; default: break; - }; + } /* * data->tzd must be registered before calling exynos_tmu_initialize(), -- cgit v1.2.3-59-g8ed1b From e35dbb4d4b4499e8a013564f0753dabc1c49e9d9 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 8 Oct 2015 14:34:06 +0900 Subject: thermal: exynos: Directly return 0 instead of using local ret variable The 'ret' variable in exynos5440_tmu_initialize() is initialized to 0 and returned as is. Replace it with direct return statement. This also fixes coccinelle warning: drivers/thermal/samsung/exynos_tmu.c:611:5-8: Unneeded variable: "ret". Return "0" on line 654 Reviewed-by: Alim Akhtar Acked-by: Lukasz Majewski Tested-by: Lukasz Majewski Signed-off-by: Krzysztof Kozlowski Signed-off-by: Eduardo Valentin --- drivers/thermal/samsung/exynos_tmu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/thermal/samsung') diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 1af7ea8dda71..f340e6edcb49 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -608,7 +608,7 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); unsigned int trim_info = 0, con, rising_threshold; - int ret = 0, threshold_code; + int threshold_code; int crit_temp = 0; /* @@ -651,7 +651,8 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev) /* Clear the PMIN in the common TMU register */ if (!data->id) writel(0, data->base_second + EXYNOS5440_TMU_PMIN); - return ret; + + return 0; } static int exynos7_tmu_initialize(struct platform_device *pdev) -- cgit v1.2.3-59-g8ed1b