thermal/drivers/mediatek/lvts: Disable monitor mode during suspend
commit 65594b3745024857f812145a58db3601d733676c upstream.
When configured in filtered mode, the LVTS thermal controller will
monitor the temperature from the sensors and trigger an interrupt once a
thermal threshold is crossed.
Currently this is true even during suspend and resume. The problem with
that is that when enabling the internal clock of the LVTS controller in
lvts_ctrl_set_enable() during resume, the temperature reading can glitch
and appear much higher than the real one, resulting in a spurious
interrupt getting generated.
Disable the temperature monitoring and give some time for the signals to
stabilize during suspend in order to prevent such spurious interrupts.
Cc: stable@vger.kernel.org
Reported-by: Hsin-Te Yuan <yuanhsinte@chromium.org>
Closes: https://lore.kernel.org/all/20241108-lvts-v1-1-eee339c6ca20@chromium.org/
Fixes: 8137bb9060 ("thermal/drivers/mediatek/lvts_thermal: Add suspend and resume")
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Link: https://lore.kernel.org/r/20250113-mt8192-lvts-filtered-suspend-fix-v2-1-07a25200c7c6@collabora.com
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
9580b60365
commit
0131251d93
@@ -860,6 +860,32 @@ static int lvts_ctrl_init(struct device *dev, struct lvts_domain *lvts_td,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lvts_ctrl_monitor_enable(struct device *dev, struct lvts_ctrl *lvts_ctrl, bool enable)
|
||||
{
|
||||
/*
|
||||
* Bitmaps to enable each sensor on filtered mode in the MONCTL0
|
||||
* register.
|
||||
*/
|
||||
static const u8 sensor_filt_bitmap[] = { BIT(0), BIT(1), BIT(2), BIT(3) };
|
||||
u32 sensor_map = 0;
|
||||
int i;
|
||||
|
||||
if (lvts_ctrl->mode != LVTS_MSR_FILTERED_MODE)
|
||||
return;
|
||||
|
||||
if (enable) {
|
||||
lvts_for_each_valid_sensor(i, lvts_ctrl)
|
||||
sensor_map |= sensor_filt_bitmap[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Bits:
|
||||
* 9: Single point access flow
|
||||
* 0-3: Enable sensing point 0-3
|
||||
*/
|
||||
writel(sensor_map | BIT(9), LVTS_MONCTL0(lvts_ctrl->base));
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point the configuration register is the only place in the
|
||||
* driver where we write multiple values. Per hardware constraint,
|
||||
@@ -1381,8 +1407,11 @@ static int lvts_suspend(struct device *dev)
|
||||
|
||||
lvts_td = dev_get_drvdata(dev);
|
||||
|
||||
for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
|
||||
for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
|
||||
lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], false);
|
||||
usleep_range(100, 200);
|
||||
lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], false);
|
||||
}
|
||||
|
||||
clk_disable_unprepare(lvts_td->clk);
|
||||
|
||||
@@ -1400,8 +1429,11 @@ static int lvts_resume(struct device *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < lvts_td->num_lvts_ctrl; i++)
|
||||
for (i = 0; i < lvts_td->num_lvts_ctrl; i++) {
|
||||
lvts_ctrl_set_enable(&lvts_td->lvts_ctrl[i], true);
|
||||
usleep_range(100, 200);
|
||||
lvts_ctrl_monitor_enable(dev, &lvts_td->lvts_ctrl[i], true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user