Weird interaction between thermal and cpufreq drivers
Hello linux-pm,
I'm seeing a weird bug, where the thermal driver(*) returns bogus temperatures once I lower the CPU frequency.
(*) drivers/thermal/tango_thermal.c
The setup: I'm using next-20160428
(Is it a good idea to test on linux-next?
Are there bugs lurking there that get sorted out later?)
I have a script which prints /sys/class/thermal/thermal_zone0/temp every second.
When the CPU is running at nominal speed, these values seem correct. ("seem" because I don't have the HW to calibrate the thermometer.)
But once I lower the frequency of the CPU(*), the script starts printing bogus values like 29000 (my driver's minimum) and very high temps like 100000 or even 137000!
(*) echo 135000 > /sys/devices/system/cpu/cpufreq/scaling_max_freq I'm using the performance governor, so everything should be manual, if I understand correctly.
I looked at timing issues in my driver. I do have an obvious usleep_range(10, 20); in my code. IIUC, this primitive will use the underlying Cortex A9 twd block, which does introduce errors on frequency changes, so I switched it to udelay(100); This one should only use the platform tick counter, which ticks at a constant speed. But I still have the issues.
Any idea what could be going wrong?
I guess I can test on v4.6-rc5
Regards.
Quoted 2 lines · Mason
I'm seeing a weird bug, where the thermal
driver(*)returns bogus temperatures once I lower the CPU frequency.
Egg on my face...
cpufreq was a red herring. I simply failed to initialize TEMPSI_CFG. (And the hardware playfully sets it to an arbitrary value at reset.) Patch incoming.
Regards.
PATCH 1/1 thermal: tango: initialize TEMPSI_CFG
From: Marc Gonzalez <[email protected]>
TEMPSI_CFG is not equal to 0 at reset. It must be initialized.
--- drivers/thermal/tango_thermal.c | 1 + 1 file changed, 1 insertion(+)
drivers/thermal/tango_thermal.c +1 -0
@@ -80,6 +80,7 @@ static int tango_thermal_probe(struct platform_device *pdev)return PTR_ERR (priv->base); priv->thresh_idx =IDX_MIN ; +writel (0 , priv->base +TEMPSI_CFG );writel (CMD_ON , priv->base +TEMPSI_CMD ); tzdev =devm_thermal_zone_of_sensor_register (&pdev->dev,0 , priv, &ops);
Signature · 1 line
2.8.1