Starting with commit d92ed2c9d3ff ("thermal: imx: Use driver's local
data to decide whether to run a measurement") this driver stared using
irq_enabled flag to make decision to power on/off the thermal core. This
triggered a regression, where after reaching critical temperature, alarm
IRQ handler set irq_enabled to false, disabled thermal core and was not
able read temperature and disable cooling sequence.
In case the cooling device is "CPU/GPU freq", the system will run with
reduce performance until next reboot.
To solve this issue, we need to move all parts implementing hand made
runtime power management and let it handle actual runtime PM framework.
Fixes: d92ed2c9d3ff ("thermal: imx: Use driver's local data to decide whether to run a measurement")
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
drivers/thermal/imx_thermal.c | 143 +++++++++++++++++++++-------------
1 file changed, 89 insertions(+), 54 deletions(-)
@@ -252,44 +254,15 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)conststructthermal_soc_data*soc_data=data->socdata;structregmap*map=data->tempmon;unsignedintn_meas;-boolwait,run_measurement;u32val;+intret;-run_measurement=!data->irq_enabled;-if(!run_measurement){-/* Check if a measurement is currently in progress */-regmap_read(map,soc_data->temp_data,&val);-wait=!(val&soc_data->temp_valid_mask);-}else{-/*-*Everytimewemeasurethetemperature,wewillpoweronthe-*temperaturesensor,enablemeasurements,takeareading,-*disablemeasurements,poweroffthetemperaturesensor.-*/-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);--wait=true;-}--/*-*Accordingtothetempsensordesigners,itmayrequireupto~17us-*tocompleteameasurement.-*/-if(wait)-usleep_range(20,50);+ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;regmap_read(map,soc_data->temp_data,&val);-if(run_measurement){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);-}-if((val&soc_data->temp_valid_mask)==0){dev_dbg(&tz->device,"temp measurement never finished\n");return-EAGAIN;
@@ -328,6 +301,8 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)enable_irq(data->irq);}+pm_runtime_put(data->dev);+return0;}
@@ -335,24 +310,16 @@ static int imx_change_mode(struct thermal_zone_device *tz,enumthermal_device_modemode){structimx_thermal_data*data=tz->devdata;-structregmap*map=data->tempmon;-conststructthermal_soc_data*soc_data=data->socdata;if(mode==THERMAL_DEVICE_ENABLED){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);+pm_runtime_get(data->dev);if(!data->irq_enabled){data->irq_enabled=true;enable_irq(data->irq);}}else{-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);+pm_runtime_put(data->dev);if(data->irq_enabled){disable_irq(data->irq);
@@ -393,6 +360,11 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,inttemp){structimx_thermal_data*data=tz->devdata;+intret;++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;/* do not allow changing critical threshold */if(trip==IMX_TRIP_CRITICAL)
@@ -406,6 +378,8 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,imx_set_alarm_temp(data,temp);+pm_runtime_put(data->dev);+return0;}
@@ -681,6 +655,8 @@ static int imx_thermal_probe(struct platform_device *pdev)if(!data)return-ENOMEM;+data->dev=&pdev->dev;+map=syscon_regmap_lookup_by_phandle(pdev->dev.of_node,"fsl,tempmon");if(IS_ERR(map)){ret=PTR_ERR(map);
@@ -801,6 +777,14 @@ static int imx_thermal_probe(struct platform_device *pdev)regmap_write(map,data->socdata->sensor_ctrl+REG_SET,data->socdata->measure_temp_mask);+/* the core was configured and enabled just before */+pm_runtime_set_active(&pdev->dev);+pm_runtime_enable(data->dev);++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+gotodisable_runtime_pm;+data->irq_enabled=true;ret=thermal_zone_device_enable(data->tz);if(ret)
@@ -814,10 +798,15 @@ static int imx_thermal_probe(struct platform_device *pdev)gotothermal_zone_unregister;}+pm_runtime_put(data->dev);+return0;thermal_zone_unregister:thermal_zone_device_unregister(data->tz);+disable_runtime_pm:+pm_runtime_put_noidle(data->dev);+pm_runtime_disable(data->dev);clk_disable:clk_disable_unprepare(data->thermal_clk);legacy_cleanup:
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
On Tue, Oct 19, 2021 at 03:08:09PM +0200, Oleksij Rempel wrote:
quoted hunk
Starting with commit d92ed2c9d3ff ("thermal: imx: Use driver's local
data to decide whether to run a measurement") this driver stared using
irq_enabled flag to make decision to power on/off the thermal core. This
triggered a regression, where after reaching critical temperature, alarm
IRQ handler set irq_enabled to false, disabled thermal core and was not
able read temperature and disable cooling sequence.
In case the cooling device is "CPU/GPU freq", the system will run with
reduce performance until next reboot.
To solve this issue, we need to move all parts implementing hand made
runtime power management and let it handle actual runtime PM framework.
Fixes: d92ed2c9d3ff ("thermal: imx: Use driver's local data to decide whether to run a measurement")
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
drivers/thermal/imx_thermal.c | 143 +++++++++++++++++++++-------------
1 file changed, 89 insertions(+), 54 deletions(-)
@@ -252,44 +254,15 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)conststructthermal_soc_data*soc_data=data->socdata;structregmap*map=data->tempmon;unsignedintn_meas;-boolwait,run_measurement;u32val;+intret;-run_measurement=!data->irq_enabled;-if(!run_measurement){-/* Check if a measurement is currently in progress */-regmap_read(map,soc_data->temp_data,&val);-wait=!(val&soc_data->temp_valid_mask);-}else{-/*-*Everytimewemeasurethetemperature,wewillpoweronthe-*temperaturesensor,enablemeasurements,takeareading,-*disablemeasurements,poweroffthetemperaturesensor.-*/-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);--wait=true;-}--/*-*Accordingtothetempsensordesigners,itmayrequireupto~17us-*tocompleteameasurement.-*/-if(wait)-usleep_range(20,50);+ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;regmap_read(map,soc_data->temp_data,&val);-if(run_measurement){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);-}-if((val&soc_data->temp_valid_mask)==0){dev_dbg(&tz->device,"temp measurement never finished\n");return-EAGAIN;
@@ -328,6 +301,8 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)enable_irq(data->irq);}+pm_runtime_put(data->dev);+return0;}
@@ -335,24 +310,16 @@ static int imx_change_mode(struct thermal_zone_device *tz,enumthermal_device_modemode){structimx_thermal_data*data=tz->devdata;-structregmap*map=data->tempmon;-conststructthermal_soc_data*soc_data=data->socdata;if(mode==THERMAL_DEVICE_ENABLED){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);+pm_runtime_get(data->dev);if(!data->irq_enabled){data->irq_enabled=true;enable_irq(data->irq);}}else{-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);+pm_runtime_put(data->dev);if(data->irq_enabled){disable_irq(data->irq);
@@ -393,6 +360,11 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,inttemp){structimx_thermal_data*data=tz->devdata;+intret;++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;/* do not allow changing critical threshold */if(trip==IMX_TRIP_CRITICAL)
@@ -406,6 +378,8 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,imx_set_alarm_temp(data,temp);+pm_runtime_put(data->dev);+return0;}
@@ -681,6 +655,8 @@ static int imx_thermal_probe(struct platform_device *pdev)if(!data)return-ENOMEM;+data->dev=&pdev->dev;+map=syscon_regmap_lookup_by_phandle(pdev->dev.of_node,"fsl,tempmon");if(IS_ERR(map)){ret=PTR_ERR(map);
@@ -801,6 +777,14 @@ static int imx_thermal_probe(struct platform_device *pdev)regmap_write(map,data->socdata->sensor_ctrl+REG_SET,data->socdata->measure_temp_mask);+/* the core was configured and enabled just before */+pm_runtime_set_active(&pdev->dev);+pm_runtime_enable(data->dev);++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+gotodisable_runtime_pm;+data->irq_enabled=true;ret=thermal_zone_device_enable(data->tz);if(ret)
@@ -814,10 +798,15 @@ static int imx_thermal_probe(struct platform_device *pdev)gotothermal_zone_unregister;}+pm_runtime_put(data->dev);+return0;thermal_zone_unregister:thermal_zone_device_unregister(data->tz);+disable_runtime_pm:+pm_runtime_put_noidle(data->dev);+pm_runtime_disable(data->dev);clk_disable:clk_disable_unprepare(data->thermal_clk);legacy_cleanup:
From: Petr Benes <hidden> Date: 2021-10-20 15:53:18
On Wed, 20 Oct 2021 at 07:05, Oleksij Rempel [off-list ref] wrote:
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
Hi Oleksij,
It works good. with PM as well as without PM. The only minor issue I found is,
that the first temperature reading (when the driver probes) fails. That is
(val & soc_data->temp_valid_mask) == 0) holds true. How does
pm_runtime_resume_and_get() behave in imx_thermal_probe()?
Does it go through imx_thermal_runtime_resume() with usleep_range()?
On Tue, Oct 19, 2021 at 03:08:09PM +0200, Oleksij Rempel wrote:
quoted
Starting with commit d92ed2c9d3ff ("thermal: imx: Use driver's local
data to decide whether to run a measurement") this driver stared using
irq_enabled flag to make decision to power on/off the thermal core. This
triggered a regression, where after reaching critical temperature, alarm
IRQ handler set irq_enabled to false, disabled thermal core and was not
able read temperature and disable cooling sequence.
In case the cooling device is "CPU/GPU freq", the system will run with
reduce performance until next reboot.
To solve this issue, we need to move all parts implementing hand made
runtime power management and let it handle actual runtime PM framework.
Fixes: d92ed2c9d3ff ("thermal: imx: Use driver's local data to decide whether to run a measurement")
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
drivers/thermal/imx_thermal.c | 143 +++++++++++++++++++++-------------
1 file changed, 89 insertions(+), 54 deletions(-)
@@ -252,44 +254,15 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)conststructthermal_soc_data*soc_data=data->socdata;structregmap*map=data->tempmon;unsignedintn_meas;-boolwait,run_measurement;u32val;+intret;-run_measurement=!data->irq_enabled;-if(!run_measurement){-/* Check if a measurement is currently in progress */-regmap_read(map,soc_data->temp_data,&val);-wait=!(val&soc_data->temp_valid_mask);-}else{-/*-*Everytimewemeasurethetemperature,wewillpoweronthe-*temperaturesensor,enablemeasurements,takeareading,-*disablemeasurements,poweroffthetemperaturesensor.-*/-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);--wait=true;-}--/*-*Accordingtothetempsensordesigners,itmayrequireupto~17us-*tocompleteameasurement.-*/-if(wait)-usleep_range(20,50);+ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;regmap_read(map,soc_data->temp_data,&val);-if(run_measurement){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);-}-if((val&soc_data->temp_valid_mask)==0){dev_dbg(&tz->device,"temp measurement never finished\n");return-EAGAIN;
@@ -328,6 +301,8 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)enable_irq(data->irq);}+pm_runtime_put(data->dev);+return0;}
@@ -335,24 +310,16 @@ static int imx_change_mode(struct thermal_zone_device *tz,enumthermal_device_modemode){structimx_thermal_data*data=tz->devdata;-structregmap*map=data->tempmon;-conststructthermal_soc_data*soc_data=data->socdata;if(mode==THERMAL_DEVICE_ENABLED){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);+pm_runtime_get(data->dev);if(!data->irq_enabled){data->irq_enabled=true;enable_irq(data->irq);}}else{-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);+pm_runtime_put(data->dev);if(data->irq_enabled){disable_irq(data->irq);
@@ -393,6 +360,11 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,inttemp){structimx_thermal_data*data=tz->devdata;+intret;++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;/* do not allow changing critical threshold */if(trip==IMX_TRIP_CRITICAL)
@@ -406,6 +378,8 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,imx_set_alarm_temp(data,temp);+pm_runtime_put(data->dev);+return0;}
@@ -681,6 +655,8 @@ static int imx_thermal_probe(struct platform_device *pdev)if(!data)return-ENOMEM;+data->dev=&pdev->dev;+map=syscon_regmap_lookup_by_phandle(pdev->dev.of_node,"fsl,tempmon");if(IS_ERR(map)){ret=PTR_ERR(map);
@@ -801,6 +777,14 @@ static int imx_thermal_probe(struct platform_device *pdev)regmap_write(map,data->socdata->sensor_ctrl+REG_SET,data->socdata->measure_temp_mask);+/* the core was configured and enabled just before */+pm_runtime_set_active(&pdev->dev);+pm_runtime_enable(data->dev);++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+gotodisable_runtime_pm;+data->irq_enabled=true;ret=thermal_zone_device_enable(data->tz);if(ret)
@@ -814,10 +798,15 @@ static int imx_thermal_probe(struct platform_device *pdev)gotothermal_zone_unregister;}+pm_runtime_put(data->dev);+return0;thermal_zone_unregister:thermal_zone_device_unregister(data->tz);+disable_runtime_pm:+pm_runtime_put_noidle(data->dev);+pm_runtime_disable(data->dev);clk_disable:clk_disable_unprepare(data->thermal_clk);legacy_cleanup:
Hi Petr,
On Wed, Oct 20, 2021 at 05:53:03PM +0200, Petr Benes wrote:
On Wed, 20 Oct 2021 at 07:05, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
Hi Oleksij,
It works good. with PM as well as without PM. The only minor issue I found is,
that the first temperature reading (when the driver probes) fails. That is
(val & soc_data->temp_valid_mask) == 0) holds true. How does
pm_runtime_resume_and_get() behave in imx_thermal_probe()?
Does it go through imx_thermal_runtime_resume() with usleep_range()?
On the first temperature reading, the PM and part of HW is not
initialized. Current probe sequence is racy and has at least following
issues:
- thermal_zone_device_register is executed before HW init was completed.
It kind of worked before my patch, becaus part of reinit was done by
temperature init. It worked, since the irq_enabled flag was not set,
but potentially would run enable_irq() two times if device is
overheated on probe.
- the imx_thermal core is potentially disable after first race
condition:
CPU0 CPU1
thermal_zone_device_register()
imx_get_temp()
irq_enabled == false
power_up
read_temp
power_up
power_down
irq_enabled = true;
... at this point imx_thermal is powered down for some amount of time,
over temperature IRQ will not be triggered for some amount of time.
- if some part after thermal_zone_device_register() would fail or
deferred, the worker polling temperature will run in to NULL pointer.
This issue already happened...
After migrating to runtime PM, one of issues started to be visible even
on normal conditions.
I'll send one more patch with reworking probe sequence.
quoted
On Tue, Oct 19, 2021 at 03:08:09PM +0200, Oleksij Rempel wrote:
quoted
Starting with commit d92ed2c9d3ff ("thermal: imx: Use driver's local
data to decide whether to run a measurement") this driver stared using
irq_enabled flag to make decision to power on/off the thermal core. This
triggered a regression, where after reaching critical temperature, alarm
IRQ handler set irq_enabled to false, disabled thermal core and was not
able read temperature and disable cooling sequence.
In case the cooling device is "CPU/GPU freq", the system will run with
reduce performance until next reboot.
To solve this issue, we need to move all parts implementing hand made
runtime power management and let it handle actual runtime PM framework.
Fixes: d92ed2c9d3ff ("thermal: imx: Use driver's local data to decide whether to run a measurement")
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
drivers/thermal/imx_thermal.c | 143 +++++++++++++++++++++-------------
1 file changed, 89 insertions(+), 54 deletions(-)
@@ -252,44 +254,15 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)conststructthermal_soc_data*soc_data=data->socdata;structregmap*map=data->tempmon;unsignedintn_meas;-boolwait,run_measurement;u32val;+intret;-run_measurement=!data->irq_enabled;-if(!run_measurement){-/* Check if a measurement is currently in progress */-regmap_read(map,soc_data->temp_data,&val);-wait=!(val&soc_data->temp_valid_mask);-}else{-/*-*Everytimewemeasurethetemperature,wewillpoweronthe-*temperaturesensor,enablemeasurements,takeareading,-*disablemeasurements,poweroffthetemperaturesensor.-*/-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);--wait=true;-}--/*-*Accordingtothetempsensordesigners,itmayrequireupto~17us-*tocompleteameasurement.-*/-if(wait)-usleep_range(20,50);+ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;regmap_read(map,soc_data->temp_data,&val);-if(run_measurement){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);-}-if((val&soc_data->temp_valid_mask)==0){dev_dbg(&tz->device,"temp measurement never finished\n");return-EAGAIN;
@@ -328,6 +301,8 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)enable_irq(data->irq);}+pm_runtime_put(data->dev);+return0;}
@@ -335,24 +310,16 @@ static int imx_change_mode(struct thermal_zone_device *tz,enumthermal_device_modemode){structimx_thermal_data*data=tz->devdata;-structregmap*map=data->tempmon;-conststructthermal_soc_data*soc_data=data->socdata;if(mode==THERMAL_DEVICE_ENABLED){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);+pm_runtime_get(data->dev);if(!data->irq_enabled){data->irq_enabled=true;enable_irq(data->irq);}}else{-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);+pm_runtime_put(data->dev);if(data->irq_enabled){disable_irq(data->irq);
@@ -393,6 +360,11 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,inttemp){structimx_thermal_data*data=tz->devdata;+intret;++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;/* do not allow changing critical threshold */if(trip==IMX_TRIP_CRITICAL)
@@ -406,6 +378,8 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,imx_set_alarm_temp(data,temp);+pm_runtime_put(data->dev);+return0;}
@@ -681,6 +655,8 @@ static int imx_thermal_probe(struct platform_device *pdev)if(!data)return-ENOMEM;+data->dev=&pdev->dev;+map=syscon_regmap_lookup_by_phandle(pdev->dev.of_node,"fsl,tempmon");if(IS_ERR(map)){ret=PTR_ERR(map);
@@ -801,6 +777,14 @@ static int imx_thermal_probe(struct platform_device *pdev)regmap_write(map,data->socdata->sensor_ctrl+REG_SET,data->socdata->measure_temp_mask);+/* the core was configured and enabled just before */+pm_runtime_set_active(&pdev->dev);+pm_runtime_enable(data->dev);++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+gotodisable_runtime_pm;+data->irq_enabled=true;ret=thermal_zone_device_enable(data->tz);if(ret)
@@ -814,10 +798,15 @@ static int imx_thermal_probe(struct platform_device *pdev)gotothermal_zone_unregister;}+pm_runtime_put(data->dev);+return0;thermal_zone_unregister:thermal_zone_device_unregister(data->tz);+disable_runtime_pm:+pm_runtime_put_noidle(data->dev);+pm_runtime_disable(data->dev);clk_disable:clk_disable_unprepare(data->thermal_clk);legacy_cleanup:
From: Daniel Lezcano <hidden> Date: 2021-10-21 07:43:19
On 21/10/2021 09:20, Oleksij Rempel wrote:
Hi Petr,
On Wed, Oct 20, 2021 at 05:53:03PM +0200, Petr Benes wrote:
quoted
On Wed, 20 Oct 2021 at 07:05, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
Hi Oleksij,
It works good. with PM as well as without PM. The only minor issue I found is,
that the first temperature reading (when the driver probes) fails. That is
(val & soc_data->temp_valid_mask) == 0) holds true. How does
pm_runtime_resume_and_get() behave in imx_thermal_probe()?
Does it go through imx_thermal_runtime_resume() with usleep_range()?
On the first temperature reading, the PM and part of HW is not
initialized. Current probe sequence is racy and has at least following
issues:
- thermal_zone_device_register is executed before HW init was completed.
It kind of worked before my patch, becaus part of reinit was done by
temperature init. It worked, since the irq_enabled flag was not set,
but potentially would run enable_irq() two times if device is
overheated on probe.
- the imx_thermal core is potentially disable after first race
condition:
CPU0 CPU1
thermal_zone_device_register()
imx_get_temp()
irq_enabled == false
power_up
read_temp
power_up
power_down
irq_enabled = true;
... at this point imx_thermal is powered down for some amount of time,
over temperature IRQ will not be triggered for some amount of time.
- if some part after thermal_zone_device_register() would fail or
deferred, the worker polling temperature will run in to NULL pointer.
This issue already happened...
After migrating to runtime PM, one of issues started to be visible even
on normal conditions.
I'll send one more patch with reworking probe sequence.
On Thu, Oct 21, 2021 at 09:41:35AM +0200, Daniel Lezcano wrote:
On 21/10/2021 09:20, Oleksij Rempel wrote:
quoted
Hi Petr,
On Wed, Oct 20, 2021 at 05:53:03PM +0200, Petr Benes wrote:
quoted
On Wed, 20 Oct 2021 at 07:05, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
Hi Oleksij,
It works good. with PM as well as without PM. The only minor issue I found is,
that the first temperature reading (when the driver probes) fails. That is
(val & soc_data->temp_valid_mask) == 0) holds true. How does
pm_runtime_resume_and_get() behave in imx_thermal_probe()?
Does it go through imx_thermal_runtime_resume() with usleep_range()?
On the first temperature reading, the PM and part of HW is not
initialized. Current probe sequence is racy and has at least following
issues:
- thermal_zone_device_register is executed before HW init was completed.
It kind of worked before my patch, becaus part of reinit was done by
temperature init. It worked, since the irq_enabled flag was not set,
but potentially would run enable_irq() two times if device is
overheated on probe.
- the imx_thermal core is potentially disable after first race
condition:
CPU0 CPU1
thermal_zone_device_register()
imx_get_temp()
irq_enabled == false
power_up
read_temp
power_up
power_down
irq_enabled = true;
... at this point imx_thermal is powered down for some amount of time,
over temperature IRQ will not be triggered for some amount of time.
- if some part after thermal_zone_device_register() would fail or
deferred, the worker polling temperature will run in to NULL pointer.
This issue already happened...
After migrating to runtime PM, one of issues started to be visible even
on normal conditions.
I'll send one more patch with reworking probe sequence.
Are you planning to send a v3 with this patch? Or a separate patch?
I'm OK with both variants. What do you prefer?
I'll do i on top of PM patch to reduce refactoring overhead, if you OK
about it.
Regards,
Oleksij
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Daniel Lezcano <hidden> Date: 2021-10-21 07:56:20
On 21/10/2021 09:44, Oleksij Rempel wrote:
On Thu, Oct 21, 2021 at 09:41:35AM +0200, Daniel Lezcano wrote:
quoted
On 21/10/2021 09:20, Oleksij Rempel wrote:
quoted
Hi Petr,
On Wed, Oct 20, 2021 at 05:53:03PM +0200, Petr Benes wrote:
quoted
On Wed, 20 Oct 2021 at 07:05, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
Hi Oleksij,
It works good. with PM as well as without PM. The only minor issue I found is,
that the first temperature reading (when the driver probes) fails. That is
(val & soc_data->temp_valid_mask) == 0) holds true. How does
pm_runtime_resume_and_get() behave in imx_thermal_probe()?
Does it go through imx_thermal_runtime_resume() with usleep_range()?
On the first temperature reading, the PM and part of HW is not
initialized. Current probe sequence is racy and has at least following
issues:
- thermal_zone_device_register is executed before HW init was completed.
It kind of worked before my patch, becaus part of reinit was done by
temperature init. It worked, since the irq_enabled flag was not set,
but potentially would run enable_irq() two times if device is
overheated on probe.
- the imx_thermal core is potentially disable after first race
condition:
CPU0 CPU1
thermal_zone_device_register()
imx_get_temp()
irq_enabled == false
power_up
read_temp
power_up
power_down
irq_enabled = true;
... at this point imx_thermal is powered down for some amount of time,
over temperature IRQ will not be triggered for some amount of time.
- if some part after thermal_zone_device_register() would fail or
deferred, the worker polling temperature will run in to NULL pointer.
This issue already happened...
After migrating to runtime PM, one of issues started to be visible even
on normal conditions.
I'll send one more patch with reworking probe sequence.
Are you planning to send a v3 with this patch? Or a separate patch?
I'm OK with both variants. What do you prefer?
I'll do i on top of PM patch to reduce refactoring overhead, if you OK
about it.
Hi Petr,
On Wed, Oct 20, 2021 at 05:53:03PM +0200, Petr Benes wrote:
On Wed, 20 Oct 2021 at 07:05, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
Hi Oleksij,
It works good. with PM as well as without PM. The only minor issue I found is,
that the first temperature reading (when the driver probes) fails. That is
(val & soc_data->temp_valid_mask) == 0) holds true. How does
pm_runtime_resume_and_get() behave in imx_thermal_probe()?
Does it go through imx_thermal_runtime_resume() with usleep_range()?
How exactly did you reproduce it? Even more or less understanding how
this can potentially happen, i never had this issue on my HW. Is it something
HW specific?
Even after executing this command:
echo disabled > /sys/class/thermal/thermal_zone0/mode
cat /sys/class/thermal/thermal_zone0/temp
In this case, IRQ is disabled and on each manual temp read, driver starts
actively using runtime PM. I still never get (val & soc_data->temp_valid_mask)
== 0)..
quoted
On Tue, Oct 19, 2021 at 03:08:09PM +0200, Oleksij Rempel wrote:
quoted
Starting with commit d92ed2c9d3ff ("thermal: imx: Use driver's local
data to decide whether to run a measurement") this driver stared using
irq_enabled flag to make decision to power on/off the thermal core. This
triggered a regression, where after reaching critical temperature, alarm
IRQ handler set irq_enabled to false, disabled thermal core and was not
able read temperature and disable cooling sequence.
In case the cooling device is "CPU/GPU freq", the system will run with
reduce performance until next reboot.
To solve this issue, we need to move all parts implementing hand made
runtime power management and let it handle actual runtime PM framework.
Fixes: d92ed2c9d3ff ("thermal: imx: Use driver's local data to decide whether to run a measurement")
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
drivers/thermal/imx_thermal.c | 143 +++++++++++++++++++++-------------
1 file changed, 89 insertions(+), 54 deletions(-)
@@ -252,44 +254,15 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)conststructthermal_soc_data*soc_data=data->socdata;structregmap*map=data->tempmon;unsignedintn_meas;-boolwait,run_measurement;u32val;+intret;-run_measurement=!data->irq_enabled;-if(!run_measurement){-/* Check if a measurement is currently in progress */-regmap_read(map,soc_data->temp_data,&val);-wait=!(val&soc_data->temp_valid_mask);-}else{-/*-*Everytimewemeasurethetemperature,wewillpoweronthe-*temperaturesensor,enablemeasurements,takeareading,-*disablemeasurements,poweroffthetemperaturesensor.-*/-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);--wait=true;-}--/*-*Accordingtothetempsensordesigners,itmayrequireupto~17us-*tocompleteameasurement.-*/-if(wait)-usleep_range(20,50);+ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;regmap_read(map,soc_data->temp_data,&val);-if(run_measurement){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);-}-if((val&soc_data->temp_valid_mask)==0){dev_dbg(&tz->device,"temp measurement never finished\n");return-EAGAIN;
@@ -328,6 +301,8 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)enable_irq(data->irq);}+pm_runtime_put(data->dev);+return0;}
@@ -335,24 +310,16 @@ static int imx_change_mode(struct thermal_zone_device *tz,enumthermal_device_modemode){structimx_thermal_data*data=tz->devdata;-structregmap*map=data->tempmon;-conststructthermal_soc_data*soc_data=data->socdata;if(mode==THERMAL_DEVICE_ENABLED){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);+pm_runtime_get(data->dev);if(!data->irq_enabled){data->irq_enabled=true;enable_irq(data->irq);}}else{-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);+pm_runtime_put(data->dev);if(data->irq_enabled){disable_irq(data->irq);
@@ -393,6 +360,11 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,inttemp){structimx_thermal_data*data=tz->devdata;+intret;++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;/* do not allow changing critical threshold */if(trip==IMX_TRIP_CRITICAL)
@@ -406,6 +378,8 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,imx_set_alarm_temp(data,temp);+pm_runtime_put(data->dev);+return0;}
@@ -681,6 +655,8 @@ static int imx_thermal_probe(struct platform_device *pdev)if(!data)return-ENOMEM;+data->dev=&pdev->dev;+map=syscon_regmap_lookup_by_phandle(pdev->dev.of_node,"fsl,tempmon");if(IS_ERR(map)){ret=PTR_ERR(map);
@@ -801,6 +777,14 @@ static int imx_thermal_probe(struct platform_device *pdev)regmap_write(map,data->socdata->sensor_ctrl+REG_SET,data->socdata->measure_temp_mask);+/* the core was configured and enabled just before */+pm_runtime_set_active(&pdev->dev);+pm_runtime_enable(data->dev);++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+gotodisable_runtime_pm;+data->irq_enabled=true;ret=thermal_zone_device_enable(data->tz);if(ret)
@@ -814,10 +798,15 @@ static int imx_thermal_probe(struct platform_device *pdev)gotothermal_zone_unregister;}+pm_runtime_put(data->dev);+return0;thermal_zone_unregister:thermal_zone_device_unregister(data->tz);+disable_runtime_pm:+pm_runtime_put_noidle(data->dev);+pm_runtime_disable(data->dev);clk_disable:clk_disable_unprepare(data->thermal_clk);legacy_cleanup:
From: Petr Benes <hidden> Date: 2021-10-25 11:06:26
Hi Oleksij,
On Thu, 21 Oct 2021 at 19:21, Oleksij Rempel [off-list ref] wrote:
Hi Petr,
On Wed, Oct 20, 2021 at 05:53:03PM +0200, Petr Benes wrote:
quoted
On Wed, 20 Oct 2021 at 07:05, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
Hi Oleksij,
It works good. with PM as well as without PM. The only minor issue I found is,
that the first temperature reading (when the driver probes) fails. That is
(val & soc_data->temp_valid_mask) == 0) holds true. How does
pm_runtime_resume_and_get() behave in imx_thermal_probe()?
Does it go through imx_thermal_runtime_resume() with usleep_range()?
How exactly did you reproduce it? Even more or less understanding how
I just placed my debug print into get_temp()
if ((val & soc_data->temp_valid_mask) == 0) {
dev_dbg(&tz->device, "temp measurement never finished\n");
printk("Wrong temperature reading!!!!!!\n");
return -EAGAIN;
}
this can potentially happen, i never had this issue on my HW. Is it something
HW specific?
IMHO it is just product of the following sequence:
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(data->dev);
pm_runtime_resume_and_get(data->dev);
thermal_zone_device_enable(data->tz);
With assumption imx_thermal_runtime_resume() didn't run,
hence the sensor didn't get enough time to come up.
I didn't have time to spend it on and you have better knowledge of the
area. If it is not that straightforward I can try to diagnose it better.
Even after executing this command:
echo disabled > /sys/class/thermal/thermal_zone0/mode
cat /sys/class/thermal/thermal_zone0/temp
In this case, IRQ is disabled and on each manual temp read, driver starts
actively using runtime PM. I still never get (val & soc_data->temp_valid_mask)
== 0)..
quoted
quoted
On Tue, Oct 19, 2021 at 03:08:09PM +0200, Oleksij Rempel wrote:
quoted
Starting with commit d92ed2c9d3ff ("thermal: imx: Use driver's local
data to decide whether to run a measurement") this driver stared using
irq_enabled flag to make decision to power on/off the thermal core. This
triggered a regression, where after reaching critical temperature, alarm
IRQ handler set irq_enabled to false, disabled thermal core and was not
able read temperature and disable cooling sequence.
In case the cooling device is "CPU/GPU freq", the system will run with
reduce performance until next reboot.
To solve this issue, we need to move all parts implementing hand made
runtime power management and let it handle actual runtime PM framework.
Fixes: d92ed2c9d3ff ("thermal: imx: Use driver's local data to decide whether to run a measurement")
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
drivers/thermal/imx_thermal.c | 143 +++++++++++++++++++++-------------
1 file changed, 89 insertions(+), 54 deletions(-)
@@ -252,44 +254,15 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)conststructthermal_soc_data*soc_data=data->socdata;structregmap*map=data->tempmon;unsignedintn_meas;-boolwait,run_measurement;u32val;+intret;-run_measurement=!data->irq_enabled;-if(!run_measurement){-/* Check if a measurement is currently in progress */-regmap_read(map,soc_data->temp_data,&val);-wait=!(val&soc_data->temp_valid_mask);-}else{-/*-*Everytimewemeasurethetemperature,wewillpoweronthe-*temperaturesensor,enablemeasurements,takeareading,-*disablemeasurements,poweroffthetemperaturesensor.-*/-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);--wait=true;-}--/*-*Accordingtothetempsensordesigners,itmayrequireupto~17us-*tocompleteameasurement.-*/-if(wait)-usleep_range(20,50);+ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;regmap_read(map,soc_data->temp_data,&val);-if(run_measurement){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);-}-if((val&soc_data->temp_valid_mask)==0){dev_dbg(&tz->device,"temp measurement never finished\n");return-EAGAIN;
@@ -328,6 +301,8 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)enable_irq(data->irq);}+pm_runtime_put(data->dev);+return0;}
@@ -335,24 +310,16 @@ static int imx_change_mode(struct thermal_zone_device *tz,enumthermal_device_modemode){structimx_thermal_data*data=tz->devdata;-structregmap*map=data->tempmon;-conststructthermal_soc_data*soc_data=data->socdata;if(mode==THERMAL_DEVICE_ENABLED){-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->power_down_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->measure_temp_mask);+pm_runtime_get(data->dev);if(!data->irq_enabled){data->irq_enabled=true;enable_irq(data->irq);}}else{-regmap_write(map,soc_data->sensor_ctrl+REG_CLR,-soc_data->measure_temp_mask);-regmap_write(map,soc_data->sensor_ctrl+REG_SET,-soc_data->power_down_mask);+pm_runtime_put(data->dev);if(data->irq_enabled){disable_irq(data->irq);
@@ -393,6 +360,11 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,inttemp){structimx_thermal_data*data=tz->devdata;+intret;++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+returnret;/* do not allow changing critical threshold */if(trip==IMX_TRIP_CRITICAL)
@@ -406,6 +378,8 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip,imx_set_alarm_temp(data,temp);+pm_runtime_put(data->dev);+return0;}
@@ -681,6 +655,8 @@ static int imx_thermal_probe(struct platform_device *pdev)if(!data)return-ENOMEM;+data->dev=&pdev->dev;+map=syscon_regmap_lookup_by_phandle(pdev->dev.of_node,"fsl,tempmon");if(IS_ERR(map)){ret=PTR_ERR(map);
@@ -801,6 +777,14 @@ static int imx_thermal_probe(struct platform_device *pdev)regmap_write(map,data->socdata->sensor_ctrl+REG_SET,data->socdata->measure_temp_mask);+/* the core was configured and enabled just before */+pm_runtime_set_active(&pdev->dev);+pm_runtime_enable(data->dev);++ret=pm_runtime_resume_and_get(data->dev);+if(ret<0)+gotodisable_runtime_pm;+data->irq_enabled=true;ret=thermal_zone_device_enable(data->tz);if(ret)
@@ -814,10 +798,15 @@ static int imx_thermal_probe(struct platform_device *pdev)gotothermal_zone_unregister;}+pm_runtime_put(data->dev);+return0;thermal_zone_unregister:thermal_zone_device_unregister(data->tz);+disable_runtime_pm:+pm_runtime_put_noidle(data->dev);+pm_runtime_disable(data->dev);clk_disable:clk_disable_unprepare(data->thermal_clk);legacy_cleanup:
From: Michal Vokáč <hidden> Date: 2021-11-10 10:07:36
On 25. 10. 21 13:06, Petr Benes wrote:
Hi Oleksij,
On Thu, 21 Oct 2021 at 19:21, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr,
On Wed, Oct 20, 2021 at 05:53:03PM +0200, Petr Benes wrote:
quoted
On Wed, 20 Oct 2021 at 07:05, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
Hi Oleksij,
It works good. with PM as well as without PM. The only minor issue I found is,
that the first temperature reading (when the driver probes) fails. That is
(val & soc_data->temp_valid_mask) == 0) holds true. How does
pm_runtime_resume_and_get() behave in imx_thermal_probe()?
Does it go through imx_thermal_runtime_resume() with usleep_range()?
How exactly did you reproduce it? Even more or less understanding how
I just placed my debug print into get_temp()
if ((val & soc_data->temp_valid_mask) == 0) {
dev_dbg(&tz->device, "temp measurement never finished\n");
printk("Wrong temperature reading!!!!!!\n");
return -EAGAIN;
}
quoted
this can potentially happen, i never had this issue on my HW. Is it something
HW specific?
IMHO it is just product of the following sequence:
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(data->dev);
pm_runtime_resume_and_get(data->dev);
thermal_zone_device_enable(data->tz);
With assumption imx_thermal_runtime_resume() didn't run,
hence the sensor didn't get enough time to come up.
I didn't have time to spend it on and you have better knowledge of the
area. If it is not that straightforward I can try to diagnose it better.
Hi Oleksij,
Did you manage to further debug and reproduce this problem?
Do you plan to send the v3?
Regarding your question about the HW - this problem occured once we
upgraded the SoC on our SBC from i.MX6DL to i.MX6Q/QP. With the DualLite
we never had this problem but the Quad is getting hot quite fast.
We have pretty limited cooling options so the core is operated at its
upper temperature limits when fully loaded.
Best regards,
Michal
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Wed, Nov 10, 2021 at 11:07:31AM +0100, Michal Vokáč wrote:
On 25. 10. 21 13:06, Petr Benes wrote:
quoted
Hi Oleksij,
On Thu, 21 Oct 2021 at 19:21, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr,
On Wed, Oct 20, 2021 at 05:53:03PM +0200, Petr Benes wrote:
quoted
On Wed, 20 Oct 2021 at 07:05, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
Hi Oleksij,
It works good. with PM as well as without PM. The only minor issue I found is,
that the first temperature reading (when the driver probes) fails. That is
(val & soc_data->temp_valid_mask) == 0) holds true. How does
pm_runtime_resume_and_get() behave in imx_thermal_probe()?
Does it go through imx_thermal_runtime_resume() with usleep_range()?
How exactly did you reproduce it? Even more or less understanding how
I just placed my debug print into get_temp()
if ((val & soc_data->temp_valid_mask) == 0) {
dev_dbg(&tz->device, "temp measurement never finished\n");
printk("Wrong temperature reading!!!!!!\n");
return -EAGAIN;
}
quoted
this can potentially happen, i never had this issue on my HW. Is it something
HW specific?
IMHO it is just product of the following sequence:
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(data->dev);
pm_runtime_resume_and_get(data->dev);
thermal_zone_device_enable(data->tz);
With assumption imx_thermal_runtime_resume() didn't run,
hence the sensor didn't get enough time to come up.
I didn't have time to spend it on and you have better knowledge of the
area. If it is not that straightforward I can try to diagnose it better.
Hi Oleksij,
Did you manage to further debug and reproduce this problem?
Do you plan to send the v3?
Regarding your question about the HW - this problem occured once we
upgraded the SoC on our SBC from i.MX6DL to i.MX6Q/QP. With the DualLite
we never had this problem but the Quad is getting hot quite fast.
We have pretty limited cooling options so the core is operated at its
upper temperature limits when fully loaded.
Hi Michal,
Sorry, I was busy and lost this topic from my radar. I was not able to
reproduce it on my i.MX6Q and i.MX6QP died after other thermal voltage
experiments. Please, if you able to reproduce it, try to investigate
what is wrong, for example increasing wakeup time and/or and tracing
sleap/wake/get sequences.
Regards,
Oleksij
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Petr Benes <hidden> Date: 2021-11-15 15:02:25
Hi Oleksij,
On Thu, 11 Nov 2021 at 10:16, Oleksij Rempel [off-list ref] wrote:
On Wed, Nov 10, 2021 at 11:07:31AM +0100, Michal Vokáč wrote:
quoted
On 25. 10. 21 13:06, Petr Benes wrote:
quoted
Hi Oleksij,
On Thu, 21 Oct 2021 at 19:21, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr,
On Wed, Oct 20, 2021 at 05:53:03PM +0200, Petr Benes wrote:
quoted
On Wed, 20 Oct 2021 at 07:05, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
Hi Oleksij,
It works good. with PM as well as without PM. The only minor issue I found is,
that the first temperature reading (when the driver probes) fails. That is
(val & soc_data->temp_valid_mask) == 0) holds true. How does
pm_runtime_resume_and_get() behave in imx_thermal_probe()?
Does it go through imx_thermal_runtime_resume() with usleep_range()?
How exactly did you reproduce it? Even more or less understanding how
I just placed my debug print into get_temp()
if ((val & soc_data->temp_valid_mask) == 0) {
dev_dbg(&tz->device, "temp measurement never finished\n");
printk("Wrong temperature reading!!!!!!\n");
return -EAGAIN;
}
quoted
this can potentially happen, i never had this issue on my HW. Is it something
HW specific?
IMHO it is just product of the following sequence:
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(data->dev);
pm_runtime_resume_and_get(data->dev);
thermal_zone_device_enable(data->tz);
With assumption imx_thermal_runtime_resume() didn't run,
hence the sensor didn't get enough time to come up.
I didn't have time to spend it on and you have better knowledge of the
area. If it is not that straightforward I can try to diagnose it better.
Hi Oleksij,
Did you manage to further debug and reproduce this problem?
Do you plan to send the v3?
Regarding your question about the HW - this problem occured once we
upgraded the SoC on our SBC from i.MX6DL to i.MX6Q/QP. With the DualLite
we never had this problem but the Quad is getting hot quite fast.
We have pretty limited cooling options so the core is operated at its
upper temperature limits when fully loaded.
Hi Michal,
Sorry, I was busy and lost this topic from my radar. I was not able to
reproduce it on my i.MX6Q and i.MX6QP died after other thermal voltage
experiments. Please, if you able to reproduce it, try to investigate
what is wrong, for example increasing wakeup time and/or and tracing
sleap/wake/get sequences.
Seems it is just as easy as calling usleep_range(20, 50) when you switch on
the sensor and enable temperature measurement in imx_thermal_probe().
So, we are sure the sensor is configured and _ready_.
You call pm_runtime_set_active(), pm_runtime_enable(), and
pm_runtime_resume_and_get(). The last one doesn't call the resume
callback (which correctly handles waiting for the sensor) as the device
is already active.
On some SoCs the timing leads to a failure of the temperature readout
in thermal_zone_device_enable() which follows. I've seen it on i.MX6DL,
but cannot reproduce it on i.MX6QP for example.
Regards,
Petr
On Mon, Nov 15, 2021 at 04:02:07PM +0100, Petr Benes wrote:
Hi Oleksij,
On Thu, 11 Nov 2021 at 10:16, Oleksij Rempel [off-list ref] wrote:
quoted
On Wed, Nov 10, 2021 at 11:07:31AM +0100, Michal Vokáč wrote:
quoted
On 25. 10. 21 13:06, Petr Benes wrote:
quoted
Hi Oleksij,
On Thu, 21 Oct 2021 at 19:21, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr,
On Wed, Oct 20, 2021 at 05:53:03PM +0200, Petr Benes wrote:
quoted
On Wed, 20 Oct 2021 at 07:05, Oleksij Rempel [off-list ref] wrote:
quoted
Hi Petr and Michal,
I forgot to add you for v2 in CC. Please test/review this version.
Hi Oleksij,
It works good. with PM as well as without PM. The only minor issue I found is,
that the first temperature reading (when the driver probes) fails. That is
(val & soc_data->temp_valid_mask) == 0) holds true. How does
pm_runtime_resume_and_get() behave in imx_thermal_probe()?
Does it go through imx_thermal_runtime_resume() with usleep_range()?
How exactly did you reproduce it? Even more or less understanding how
I just placed my debug print into get_temp()
if ((val & soc_data->temp_valid_mask) == 0) {
dev_dbg(&tz->device, "temp measurement never finished\n");
printk("Wrong temperature reading!!!!!!\n");
return -EAGAIN;
}
quoted
this can potentially happen, i never had this issue on my HW. Is it something
HW specific?
IMHO it is just product of the following sequence:
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(data->dev);
pm_runtime_resume_and_get(data->dev);
thermal_zone_device_enable(data->tz);
With assumption imx_thermal_runtime_resume() didn't run,
hence the sensor didn't get enough time to come up.
I didn't have time to spend it on and you have better knowledge of the
area. If it is not that straightforward I can try to diagnose it better.
Hi Oleksij,
Did you manage to further debug and reproduce this problem?
Do you plan to send the v3?
Regarding your question about the HW - this problem occured once we
upgraded the SoC on our SBC from i.MX6DL to i.MX6Q/QP. With the DualLite
we never had this problem but the Quad is getting hot quite fast.
We have pretty limited cooling options so the core is operated at its
upper temperature limits when fully loaded.
Hi Michal,
Sorry, I was busy and lost this topic from my radar. I was not able to
reproduce it on my i.MX6Q and i.MX6QP died after other thermal voltage
experiments. Please, if you able to reproduce it, try to investigate
what is wrong, for example increasing wakeup time and/or and tracing
sleap/wake/get sequences.
Seems it is just as easy as calling usleep_range(20, 50) when you switch on
the sensor and enable temperature measurement in imx_thermal_probe().
So, we are sure the sensor is configured and _ready_.
You call pm_runtime_set_active(), pm_runtime_enable(), and
pm_runtime_resume_and_get(). The last one doesn't call the resume
callback (which correctly handles waiting for the sensor) as the device
is already active.
Ok, thx! It makes sense. I'll send new version with the fix.
Regards,
Oleksij
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel