|
15 | 15 | #include <linux/bug.h>
|
16 | 16 | #include <linux/cleanup.h>
|
17 | 17 | #include <linux/debugfs.h>
|
| 18 | +#include <linux/delay.h> |
18 | 19 | #include <linux/device.h>
|
19 | 20 | #include <linux/dmi.h>
|
20 | 21 | #include <linux/i8042.h>
|
@@ -267,6 +268,20 @@ static void ideapad_shared_exit(struct ideapad_private *priv)
|
267 | 268 | */
|
268 | 269 | #define IDEAPAD_EC_TIMEOUT 200 /* in ms */
|
269 | 270 |
|
| 271 | +/* |
| 272 | + * Some models (e.g., ThinkBook since 2024) have a low tolerance for being |
| 273 | + * polled too frequently. Doing so may break the state machine in the EC, |
| 274 | + * resulting in a hard shutdown. |
| 275 | + * |
| 276 | + * It is also observed that frequent polls may disturb the ongoing operation |
| 277 | + * and notably delay the availability of EC response. |
| 278 | + * |
| 279 | + * These values are used as the delay before the first poll and the interval |
| 280 | + * between subsequent polls to solve the above issues. |
| 281 | + */ |
| 282 | +#define IDEAPAD_EC_POLL_MIN_US 150 |
| 283 | +#define IDEAPAD_EC_POLL_MAX_US 300 |
| 284 | + |
270 | 285 | static int eval_int(acpi_handle handle, const char *name, unsigned long *res)
|
271 | 286 | {
|
272 | 287 | unsigned long long result;
|
@@ -383,7 +398,7 @@ static int read_ec_data(acpi_handle handle, unsigned long cmd, unsigned long *da
|
383 | 398 | end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;
|
384 | 399 |
|
385 | 400 | while (time_before(jiffies, end_jiffies)) {
|
386 |
| - schedule(); |
| 401 | + usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US); |
387 | 402 |
|
388 | 403 | err = eval_vpcr(handle, 1, &val);
|
389 | 404 | if (err)
|
@@ -414,7 +429,7 @@ static int write_ec_cmd(acpi_handle handle, unsigned long cmd, unsigned long dat
|
414 | 429 | end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1;
|
415 | 430 |
|
416 | 431 | while (time_before(jiffies, end_jiffies)) {
|
417 |
| - schedule(); |
| 432 | + usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US); |
418 | 433 |
|
419 | 434 | err = eval_vpcr(handle, 1, &val);
|
420 | 435 | if (err)
|
|
0 commit comments