imx: thermal: imx_get_temp might be called before sensor clock is prepared
Subsystems (2)
PATCH v2 1/1 imx: thermal: imx_get_temp might be called before sensor clock is prepared
imx_get_temp might be called before the sensor clock is prepared thus resulting in a timeout of the first attempt to read temp:
thermal thermal_zone0: failed to read out thermal zone 0 Happened to me on a Utilite Standard with IMX6 Dual SoC.
Reason is that in imx_thermal_probe thermal_zone_device_register is called before the sensor clock is prepared. thermal_zone_device_register however calls thermal_zone_device_update which eventually calls imx_get_temp.
Fix this by preparing the clock before callingthermal_zone_device_register.
v2: revised error path. Bail out and tidy up properly if we can't get the clock or fail to enable it.
--- drivers/thermal/imx_thermal.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-)
drivers/thermal/imx_thermal.c +23 -16
@@ -521,6 +521,28 @@ static int imx_thermal_probe(struct platform_device *pdev)return ret; } + data->thermal_clk =devm_clk_get (&pdev->dev,NULL ); +if (IS_ERR (data->thermal_clk)) { + ret =PTR_ERR (data->thermal_clk); +dev_err (&pdev->dev,"failed to get thermal clk: %d\n" , ret); +cpufreq_cooling_unregister (data->cdev); +return ret; + } + +/* +* Thermal sensor needs clk on to get correct value, normally +* we should enable its clk before taking measurement and disable +* clk after measurement is done, but if alarm function is enabled, +* hardware will auto measure the temperature periodically, so we +* need to keep the clk always on for alarm function. +*/ + ret =clk_prepare_enable (data->thermal_clk); +if (ret) { +dev_err (&pdev->dev,"failed to enable thermal clk: %d\n" , ret); +cpufreq_cooling_unregister (data->cdev); +return ret; + } + data->tz = thermal_zone_device_register("imx_thermal_zone", IMX_TRIP_NUM, BIT(IMX_TRIP_PASSIVE), data,
@@ -531,26 +553,11 @@ static int imx_thermal_probe(struct platform_device *pdev) ret =PTR_ERR (data->tz);dev_err (&pdev->dev,"failed to register thermal zone device %d\n" , ret); +clk_disable_unprepare (data->thermal_clk);cpufreq_cooling_unregister (data->cdev);return ret; } - data->thermal_clk =devm_clk_get (&pdev->dev,NULL ); -if (IS_ERR (data->thermal_clk)) { -dev_warn (&pdev->dev,"failed to get thermal clk!\n" ); - }else { -/* -* Thermal sensor needs clk on to get correct value, normally -* we should enable its clk before taking measurement and disable -* clk after measurement is done, but if alarm function is enabled, -* hardware will auto measure the temperature periodically, so we -* need to keep the clk always on for alarm function. -*/ - ret =clk_prepare_enable (data->thermal_clk); -if (ret) -dev_warn (&pdev->dev,"failed to enable thermal clk: %d\n" , ret); - } -/* Enable measurements at ~ 10 Hz */ regmap_write (map,TEMPSENSE1 +REG_CLR ,TEMPSENSE1_MEASURE_FREQ ); measure_freq =DIV_ROUND_UP (32768 ,10 );/* 10 Hz */
--
2.1.2
PATCH v2 1/1 imx: thermal: imx_get_temp might be called before sensor clock is prepared
Quoted 10 lines · Heiner Kallweit
imx_get_tempmight be called before the sensor clock is prepared thus resulting in a timeout of the first attempt to read temp:
thermalthermal_zone0: failed to read out thermal zone 0 Happened to me on a Utilite Standard with IMX6 Dual SoC.Reason is that in
imx_thermal_probethermal_zone_device_registeris called before the sensor clock is prepared.thermal_zone_device_registerhowever callsthermal_zone_device_updatewhich eventually callsimx_get_temp.
Quoted 5 lines
Fix this by preparing the clock before calling
thermal_zone_device_register.v2: revised error path. Bail out and tidy up properly if we can't get the clock or fail to enable it.
This paragraph usually goes below the "---".
Quoted 11 lines
Signed-off-by Heiner Kallweit <[email protected]>--- drivers/thermal/imx_thermal.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-)drivers/thermal/imx_thermal.c +0
-0
drivers/thermal/imx_thermal.c static int imx_thermal_probe(struct platform_device *pdev) · line 527
Quoted 7 lines
drivers/thermal/imx_thermal.c +4
-0@@ -521,6 +521,28 @@ static int imx_thermal_probe(struct platform_device *pdev)return ret; } + data->thermal_clk =devm_clk_get (&pdev->dev,NULL ); +if (IS_ERR (data->thermal_clk)) { + ret =PTR_ERR (data->thermal_clk); +dev_err (&pdev->dev,"failed to get thermal clk: %d\n" , ret);
I think you don't want to print that error if ret == -EPROBE_DEFER.
Quoted 52 lines
drivers/thermal/imx_thermal.c +19
-17+cpufreq_cooling_unregister (data->cdev); +return ret; + } + +/* +* Thermal sensor needs clk on to get correct value, normally +* we should enable its clk before taking measurement and disable +* clk after measurement is done, but if alarm function is enabled, +* hardware will auto measure the temperature periodically, so we +* need to keep the clk always on for alarm function. +*/ + ret =clk_prepare_enable (data->thermal_clk); +if (ret) { +dev_err (&pdev->dev,"failed to enable thermal clk: %d\n" , ret); +cpufreq_cooling_unregister (data->cdev); +return ret; + } + data->tz = thermal_zone_device_register("imx_thermal_zone", IMX_TRIP_NUM, BIT(IMX_TRIP_PASSIVE), data,@@ -531,26 +553,11 @@ static int imx_thermal_probe(struct platform_device *pdev) ret =PTR_ERR (data->tz);dev_err (&pdev->dev,"failed to register thermal zone device %d\n" , ret); +clk_disable_unprepare (data->thermal_clk);cpufreq_cooling_unregister (data->cdev);return ret; } - data->thermal_clk =devm_clk_get (&pdev->dev,NULL ); -if (IS_ERR (data->thermal_clk)) { -dev_warn (&pdev->dev,"failed to get thermal clk!\n" ); - }else { -/* -* Thermal sensor needs clk on to get correct value, normally -* we should enable its clk before taking measurement and disable -* clk after measurement is done, but if alarm function is enabled, -* hardware will auto measure the temperature periodically, so we -* need to keep the clk always on for alarm function. -*/ - ret =clk_prepare_enable (data->thermal_clk); -if (ret) -dev_warn (&pdev->dev,"failed to enable thermal clk: %d\n" , ret); - } -/* Enable measurements at ~ 10 Hz */ regmap_write (map,TEMPSENSE1 +REG_CLR ,TEMPSENSE1_MEASURE_FREQ ); measure_freq =DIV_ROUND_UP (32768 ,10 );/* 10 Hz */ --2.1.2
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-K?nig | Industrial Linux Solutions | http://www.pengutronix.de/ |