* Re: [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling
2025-05-25 20:18 [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling Rong Zhang
@ 2025-05-26 3:43 ` Mingcong Bai
2025-05-26 6:44 ` Felix Yan
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Mingcong Bai @ 2025-05-26 3:43 UTC (permalink / raw)
To: Rong Zhang, Ike Panhc, Hans de Goede, Ilpo Järvinen
Cc: platform-driver-x86, linux-kernel, stable, Eric Long,
Kexy Biscuit
Hi Rong,
在 2025/5/26 04:18, Rong Zhang 写道:
> It was reported that ideapad-laptop sometimes causes some recent (since
> 2024) Lenovo ThinkBook models shut down when:
> - suspending/resuming
> - closing/opening the lid
> - (dis)connecting a charger
> - reading/writing some sysfs properties, e.g., fan_mode, touchpad
> - pressing down some Fn keys, e.g., Brightness Up/Down (Fn+F5/F6)
> - (seldom) loading the kmod
>
> The issue has existed since the launch day of such models, and there
> have been some out-of-tree workarounds (see Link:) for the issue. One
> disables some functionalities, while another one simply shortens
> IDEAPAD_EC_TIMEOUT. The disabled functionalities have read_ec_data() in
> their call chains, which calls schedule() between each poll.
>
> It turns out that these models suffer from the indeterminacy of
> schedule() because of their low tolerance for being polled too
> frequently. Sometimes schedule() returns too soon due to the lack of
> ready tasks, causing the margin between two polls to be too short.
> In this case, the command is somehow aborted, and too many subsequent
> polls (they poll for "nothing!") may eventually break the state machine
> in the EC, resulting in a hard shutdown. This explains why shortening
> IDEAPAD_EC_TIMEOUT works around the issue - it reduces the total number
> of polls sent to the EC.
>
> Even when it doesn't lead to a shutdown, frequent polls may also disturb
> the ongoing operation and notably delay (+ 10-20ms) the availability of
> EC response. This phenomenon is unlikely to be exclusive to the models
> mentioned above, so dropping the schedule() manner should also slightly
> improve the responsiveness of various models.
>
> Fix these issues by migrating to usleep_range(150, 300). The interval is
> chosen to add some margin to the minimal 50us and considering EC
> responses are usually available after 150-2500us based on my test. It
> should be enough to fix these issues on all models subject to the EC bug
> without introducing latency on other models.
>
> Tested on ThinkBook 14 G7+ ASP and solved both issues. No regression was
> introduced in the test on a model without the EC bug (ThinkBook X IMH,
> thanks Eric).
>
> Link: https://github.com/ty2/ideapad-laptop-tb2024g6plus/commit/6c5db18c9e8109873c2c90a7d2d7f552148f7ad4
> Link: https://github.com/ferstar/ideapad-laptop-tb/commit/42d1e68e5009529d31bd23f978f636f79c023e80
> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218771
> Fixes: 6a09f21dd1e2 ("ideapad: add ACPI helpers")
> Cc: stable@vger.kernel.org
> Tested-by: Eric Long <i@hack3r.moe>
> Signed-off-by: Rong Zhang <i@rong.moe>
> ---
> drivers/platform/x86/ideapad-laptop.c | 19 +++++++++++++++++--
> 1 file changed, 17 insertions(+), 2 deletions(-)
Tested good on my Lenovo ThinkBook 14 G6+ (AHP) with the following:
- Frequent Fn+F5/F6 inputs
- Lid opening/closing to suspend: 20 times each whilst (1) plugged in
and (2) using battery power
- Plugging in and unplugging USB-C power: 20 times while running
Tested-by: Mingcong Bai <jeffbai@aosc.io>
> diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
> index ede483573fe0..b5e4da6a6779 100644
> --- a/drivers/platform/x86/ideapad-laptop.c
> +++ b/drivers/platform/x86/ideapad-laptop.c
> @@ -15,6 +15,7 @@
> #include <linux/bug.h>
> #include <linux/cleanup.h>
> #include <linux/debugfs.h>
> +#include <linux/delay.h>
> #include <linux/device.h>
> #include <linux/dmi.h>
> #include <linux/i8042.h>
> @@ -267,6 +268,20 @@ static void ideapad_shared_exit(struct ideapad_private *priv)
> */
> #define IDEAPAD_EC_TIMEOUT 200 /* in ms */
>
> +/*
> + * Some models (e.g., ThinkBook since 2024) have a low tolerance for being
> + * polled too frequently. Doing so may break the state machine in the EC,
> + * resulting in a hard shutdown.
> + *
> + * It is also observed that frequent polls may disturb the ongoing operation
> + * and notably delay the availability of EC response.
> + *
> + * These values are used as the delay before the first poll and the interval
> + * between subsequent polls to solve the above issues.
> + */
> +#define IDEAPAD_EC_POLL_MIN_US 150
> +#define IDEAPAD_EC_POLL_MAX_US 300
> +
> static int eval_int(acpi_handle handle, const char *name, unsigned long *res)
> {
> unsigned long long result;
> @@ -383,7 +398,7 @@ static int read_ec_data(acpi_handle handle, unsigned long cmd, unsigned long *da
> end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;
>
> while (time_before(jiffies, end_jiffies)) {
> - schedule();
> + usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US);
>
> err = eval_vpcr(handle, 1, &val);
> if (err)
> @@ -414,7 +429,7 @@ static int write_ec_cmd(acpi_handle handle, unsigned long cmd, unsigned long dat
> end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;
>
> while (time_before(jiffies, end_jiffies)) {
> - schedule();
> + usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US);
>
> err = eval_vpcr(handle, 1, &val);
> if (err)
>
> base-commit: a5806cd506af5a7c19bcd596e4708b5c464bfd21
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling
2025-05-25 20:18 [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling Rong Zhang
2025-05-26 3:43 ` Mingcong Bai
@ 2025-05-26 6:44 ` Felix Yan
2025-06-06 3:47 ` Minh
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Felix Yan @ 2025-05-26 6:44 UTC (permalink / raw)
To: Rong Zhang, Ike Panhc, Hans de Goede, Ilpo Järvinen
Cc: platform-driver-x86, linux-kernel, stable, Eric Long, jeffbai
[-- Attachment #1.1: Type: text/plain, Size: 5423 bytes --]
Hi Rong,
On 5/26/25 04:18, Rong Zhang wrote:
> It was reported that ideapad-laptop sometimes causes some recent (since
> 2024) Lenovo ThinkBook models shut down when:
> - suspending/resuming
> - closing/opening the lid
> - (dis)connecting a charger
> - reading/writing some sysfs properties, e.g., fan_mode, touchpad
> - pressing down some Fn keys, e.g., Brightness Up/Down (Fn+F5/F6)
> - (seldom) loading the kmod
>
> The issue has existed since the launch day of such models, and there
> have been some out-of-tree workarounds (see Link:) for the issue. One
> disables some functionalities, while another one simply shortens
> IDEAPAD_EC_TIMEOUT. The disabled functionalities have read_ec_data() in
> their call chains, which calls schedule() between each poll.
>
> It turns out that these models suffer from the indeterminacy of
> schedule() because of their low tolerance for being polled too
> frequently. Sometimes schedule() returns too soon due to the lack of
> ready tasks, causing the margin between two polls to be too short.
> In this case, the command is somehow aborted, and too many subsequent
> polls (they poll for "nothing!") may eventually break the state machine
> in the EC, resulting in a hard shutdown. This explains why shortening
> IDEAPAD_EC_TIMEOUT works around the issue - it reduces the total number
> of polls sent to the EC.
>
> Even when it doesn't lead to a shutdown, frequent polls may also disturb
> the ongoing operation and notably delay (+ 10-20ms) the availability of
> EC response. This phenomenon is unlikely to be exclusive to the models
> mentioned above, so dropping the schedule() manner should also slightly
> improve the responsiveness of various models.
>
> Fix these issues by migrating to usleep_range(150, 300). The interval is
> chosen to add some margin to the minimal 50us and considering EC
> responses are usually available after 150-2500us based on my test. It
> should be enough to fix these issues on all models subject to the EC bug
> without introducing latency on other models.
>
> Tested on ThinkBook 14 G7+ ASP and solved both issues. No regression was
> introduced in the test on a model without the EC bug (ThinkBook X IMH,
> thanks Eric).
>
> Link: https://github.com/ty2/ideapad-laptop-tb2024g6plus/commit/6c5db18c9e8109873c2c90a7d2d7f552148f7ad4
> Link: https://github.com/ferstar/ideapad-laptop-tb/commit/42d1e68e5009529d31bd23f978f636f79c023e80
> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218771
> Fixes: 6a09f21dd1e2 ("ideapad: add ACPI helpers")
> Cc: stable@vger.kernel.org
> Tested-by: Eric Long <i@hack3r.moe>
> Signed-off-by: Rong Zhang <i@rong.moe>
> ---
> drivers/platform/x86/ideapad-laptop.c | 19 +++++++++++++++++--
> 1 file changed, 17 insertions(+), 2 deletions(-)
Tested to work as expected on my ThinkBook 14 G6+ IMH (Intel model) with
the following:
- Fn+F5/F6 inputs, more responsive than before and no shutdown.
- Sleep via power button and close the lid (which is bound to sleep as
well); Wake via shaking the mouse and open lid. Both caused unexpected
shutdown before and fixed now.
Thanks for figuring out this long-standing issue!
Tested-by: Felix Yan <felixonmars@archlinux.org>
> diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
> index ede483573fe0..b5e4da6a6779 100644
> --- a/drivers/platform/x86/ideapad-laptop.c
> +++ b/drivers/platform/x86/ideapad-laptop.c
> @@ -15,6 +15,7 @@
> #include <linux/bug.h>
> #include <linux/cleanup.h>
> #include <linux/debugfs.h>
> +#include <linux/delay.h>
> #include <linux/device.h>
> #include <linux/dmi.h>
> #include <linux/i8042.h>
> @@ -267,6 +268,20 @@ static void ideapad_shared_exit(struct ideapad_private *priv)
> */
> #define IDEAPAD_EC_TIMEOUT 200 /* in ms */
>
> +/*
> + * Some models (e.g., ThinkBook since 2024) have a low tolerance for being
> + * polled too frequently. Doing so may break the state machine in the EC,
> + * resulting in a hard shutdown.
> + *
> + * It is also observed that frequent polls may disturb the ongoing operation
> + * and notably delay the availability of EC response.
> + *
> + * These values are used as the delay before the first poll and the interval
> + * between subsequent polls to solve the above issues.
> + */
> +#define IDEAPAD_EC_POLL_MIN_US 150
> +#define IDEAPAD_EC_POLL_MAX_US 300
> +
> static int eval_int(acpi_handle handle, const char *name, unsigned long *res)
> {
> unsigned long long result;
> @@ -383,7 +398,7 @@ static int read_ec_data(acpi_handle handle, unsigned long cmd, unsigned long *da
> end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;
>
> while (time_before(jiffies, end_jiffies)) {
> - schedule();
> + usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US);
>
> err = eval_vpcr(handle, 1, &val);
> if (err)
> @@ -414,7 +429,7 @@ static int write_ec_cmd(acpi_handle handle, unsigned long cmd, unsigned long dat
> end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;
>
> while (time_before(jiffies, end_jiffies)) {
> - schedule();
> + usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US);
>
> err = eval_vpcr(handle, 1, &val);
> if (err)
>
> base-commit: a5806cd506af5a7c19bcd596e4708b5c464bfd21
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling
2025-05-25 20:18 [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling Rong Zhang
2025-05-26 3:43 ` Mingcong Bai
2025-05-26 6:44 ` Felix Yan
@ 2025-06-06 3:47 ` Minh
2025-06-06 6:22 ` Sicheng Zhu
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Minh @ 2025-06-06 3:47 UTC (permalink / raw)
To: i
Cc: hdegoede, i, ikepanhc, ilpo.jarvinen, linux-kernel,
platform-driver-x86, stable
Tested to work as expected on my ThinkBook 16 G7+ ASP (Ryzen model) with
the following:
- Fn+F4/F5/F6 inputs, more responsive than before and no shutdown.
- Previous issue with suspend including close lid, sleep button,
mouse/keyboard during suspend cause shutdown has been fixed now
Tested-by: Minh Le <minhld139@gmail.com>
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling
2025-05-25 20:18 [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling Rong Zhang
` (2 preceding siblings ...)
2025-06-06 3:47 ` Minh
@ 2025-06-06 6:22 ` Sicheng Zhu
2025-06-09 7:52 ` Ilpo Järvinen
2025-06-17 10:25 ` Hai Tran
5 siblings, 0 replies; 7+ messages in thread
From: Sicheng Zhu @ 2025-06-06 6:22 UTC (permalink / raw)
To: i
Cc: hdegoede, i, ikepanhc, ilpo.jarvinen, linux-kernel,
platform-driver-x86, stable
Tested works fine on my Levono Thinkbook 14 G7+ AKP (AMD Ryzen AI 7
model) with:
- frequent Fn+F4/F5/F6 inputs, having a more sensitive response
- close lid and suspend on plugged in and using battery
Thanks for solving this problem!
Tested-by: Sicheng Zhu <Emmet_Z@outlook.com>
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling
2025-05-25 20:18 [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling Rong Zhang
` (3 preceding siblings ...)
2025-06-06 6:22 ` Sicheng Zhu
@ 2025-06-09 7:52 ` Ilpo Järvinen
2025-06-17 10:25 ` Hai Tran
5 siblings, 0 replies; 7+ messages in thread
From: Ilpo Järvinen @ 2025-06-09 7:52 UTC (permalink / raw)
To: Ike Panhc, Hans de Goede, Rong Zhang
Cc: platform-driver-x86, linux-kernel, stable, Eric Long
On Mon, 26 May 2025 04:18:07 +0800, Rong Zhang wrote:
> It was reported that ideapad-laptop sometimes causes some recent (since
> 2024) Lenovo ThinkBook models shut down when:
> - suspending/resuming
> - closing/opening the lid
> - (dis)connecting a charger
> - reading/writing some sysfs properties, e.g., fan_mode, touchpad
> - pressing down some Fn keys, e.g., Brightness Up/Down (Fn+F5/F6)
> - (seldom) loading the kmod
>
> [...]
Thank you for your contribution, it has been applied to my local
review-ilpo-fixes branch. Note it will show up in the public
platform-drivers-x86/review-ilpo-fixes branch only once I've pushed my
local branch there, which might take a while.
The list of commits applied:
[1/1] platform/x86: ideapad-laptop: use usleep_range() for EC polling
commit: 5808c34216954cd832bd4b8bc52dfa287049122b
--
i.
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling
2025-05-25 20:18 [PATCH] platform/x86: ideapad-laptop: use usleep_range() for EC polling Rong Zhang
` (4 preceding siblings ...)
2025-06-09 7:52 ` Ilpo Järvinen
@ 2025-06-17 10:25 ` Hai Tran
5 siblings, 0 replies; 7+ messages in thread
From: Hai Tran @ 2025-06-17 10:25 UTC (permalink / raw)
To: i
Cc: hdegoede, i, ikepanhc, ilpo.jarvinen, linux-kernel,
platform-driver-x86, stable, Hai Tran
Tested on my ThinkBook 16 G6+ AHP and everything is working fine now with:
- Fn+F5/F6 inputs to change brightness are not shutdown unexpectedly anymore.
- Sleep is working after closing the lid or via power button.
Tested-by: Hai Tran <hoanghaivn0406@gmail.com>
^ permalink raw reply [flat|nested] 7+ messages in thread