[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAHc4DNKmGA-MjTWdZhKygiaRwN7mHnMCf8UPUxH_V16uZifzFg@mail.gmail.com>
Date: Tue, 26 Nov 2024 16:00:42 +0800
From: Hsin-Te Yuan <yuanhsinte@...omium.org>
To: Nícolas F. R. A. Prado <nfraprado@...labora.com>
Cc: "Rafael J. Wysocki" <rafael@...nel.org>, Daniel Lezcano <daniel.lezcano@...aro.org>,
Zhang Rui <rui.zhang@...el.com>, Lukasz Luba <lukasz.luba@....com>,
Matthias Brugger <matthias.bgg@...il.com>,
AngeloGioacchino Del Regno <angelogioacchino.delregno@...labora.com>,
Alexandre Mergnat <amergnat@...libre.com>, Balsam CHIHI <bchihi@...libre.com>, kernel@...labora.com,
linux-pm@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org, linux-mediatek@...ts.infradead.org,
Hsin-Te Yuan <yuanhsinte@...omium.org>, Chen-Yu Tsai <wenst@...omium.org>,
Bernhard Rosenkränzer <bero@...libre.com>,
"Rafael J. Wysocki" <rafael.j.wysocki@...el.com>, stable@...r.kernel.org
Subject: Re: [PATCH 1/5] thermal/drivers/mediatek/lvts: Disable monitor mode
during suspend
On Tue, Nov 26, 2024 at 5:21 AM Nícolas F. R. A. Prado
<nfraprado@...labora.com> wrote:
>
> 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.
>
This sounds weird to me. On my end, the symptom is that the device
sometimes cannot suspend.
To be more precise, `echo mem > /sys/power/state` returns almost
immediately. I think the irq is more
likely to be triggered during suspension.
> Disable the temperature monitoring and give some time for the signals to
> stabilize during suspend in order to prevent such spurious interrupts.
>
> Cc: stable@...r.kernel.org
> Reported-by: Hsin-Te Yuan <yuanhsinte@...omium.org>
> Closes: https://lore.kernel.org/all/20241108-lvts-v1-1-eee339c6ca20@chromium.org/
> Fixes: 8137bb90600d ("thermal/drivers/mediatek/lvts_thermal: Add suspend and resume")
> Signed-off-by: Nícolas F. R. A. Prado <nfraprado@...labora.com>
> ---
> drivers/thermal/mediatek/lvts_thermal.c | 36 +++++++++++++++++++++++++++++++--
> 1 file changed, 34 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/thermal/mediatek/lvts_thermal.c b/drivers/thermal/mediatek/lvts_thermal.c
> index 1997e91bb3be94a3059db619238aa5787edc7675..a92ff2325c40704adc537af6995b34f93c3b0650 100644
> --- a/drivers/thermal/mediatek/lvts_thermal.c
> +++ b/drivers/thermal/mediatek/lvts_thermal.c
> @@ -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.
> + */
> + u32 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;
> }
>
> --
> 2.47.0
>
Powered by blists - more mailing lists