lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260106220949.1518571-1-jriemenschne@student.ethz.ch>
Date: Tue,  6 Jan 2026 23:09:49 +0100
From: Jakob <riemenschneiderjakob@...il.com>
To: mpearson-lenovo@...ebb.ca,
	derekjohn.clark@...il.com,
	ikepanhc@...il.com,
	hansg@...nel.org,
	ilpo.jarvinen@...ux.intel.com
Cc: platform-driver-x86@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Jakob <jriemenschne@...dent.ethz.ch>
Subject: [PATCH v1] platform/x86: ideapad-laptop: Fix resume behavior for Lenovo Yoga 15ILL9

On the Lenovo Yoga Slim 7 15ILL9, the Embedded Controller fails to restore
its state after resuming from suspend. This results in the cooling fans
remaining stopped (causing overheating), the keyboard backlight and
brightness keys becoming unresponsive, and the power button LED continuing
to pulse as if still suspended.

Testing shows that invoking the UPHK method with command 0x09 properly
resets the EC state. This single command restores fan control, fixes the
keyboard backlight and brightness keys and corrects the power LED behavior.

This patch adds a DMI quirk to invoke this method on resume.

Note: On this model, UPHK is located at \_SB.PC00.LPCB.EC0.UPHK rather
than the standard VPC2004 device, so we access it via its absolute path.

Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220505
Signed-off-by: Jakob <jriemenschne@...dent.ethz.ch>
---
 drivers/platform/x86/lenovo/ideapad-laptop.c | 56 ++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/platform/x86/lenovo/ideapad-laptop.c b/drivers/platform/x86/lenovo/ideapad-laptop.c
index 5171a077f..c9fec590a 100644
--- a/drivers/platform/x86/lenovo/ideapad-laptop.c
+++ b/drivers/platform/x86/lenovo/ideapad-laptop.c
@@ -43,6 +43,7 @@
 #include <dt-bindings/leds/common.h>
 
 #define IDEAPAD_RFKILL_DEV_NUM	3
+#define IDEAPAD_EC_UPHK_PATH "\\_SB.PC00.LPCB.EC0.UPHK"
 
 enum {
 	CFG_CAP_BT_BIT       = 16,
@@ -105,6 +106,10 @@ enum {
 	SALS_FNLOCK_OFF       = 0xf,
 };
 
+enum {
+	UPHK_FAN_RESUME = 0x9,
+};
+
 enum {
 	VPCCMD_R_VPC1 = 0x10,
 	VPCCMD_R_BL_MAX,
@@ -198,6 +203,7 @@ struct ideapad_private {
 		bool ctrl_ps2_aux_port    : 1;
 		bool usb_charging         : 1;
 		bool ymc_ec_trigger       : 1;
+		bool fan_mode_fix         : 1;
 	} features;
 	struct {
 		bool initialized;
@@ -246,6 +252,12 @@ MODULE_PARM_DESC(touchpad_ctrl_via_ec,
 	"Enable registering a 'touchpad' sysfs-attribute which can be used to manually "
 	"tell the EC to enable/disable the touchpad. This may not work on all models.");
 
+static bool fan_mode_fix;
+module_param(fan_mode_fix, bool, 0444);
+MODULE_PARM_DESC(fan_mode_fix,
+	"Enable fan-mode resume fix for laptops that stop cooling after sleep. "
+	"If you need this please report this to: platform-driver-x86@...r.kernel.org");
+
 static bool ymc_ec_trigger __read_mostly;
 module_param(ymc_ec_trigger, bool, 0444);
 MODULE_PARM_DESC(ymc_ec_trigger,
@@ -2022,6 +2034,24 @@ static const struct dmi_system_id hw_rfkill_list[] = {
 	{}
 };
 
+/*
+ * On the Lenovo Yoga Slim 15ILL9, the EC fails to restore the fan control profile after
+ * resuming from suspend, causing the fans to stop working.
+ * On this model, the driver needs to explicitly reset the fan mode
+ * on resume.
+ * See https://bugzilla.kernel.org/show_bug.cgi?id=220505
+ */
+static const struct dmi_system_id fan_mode_fix_list[] = {
+	{
+	/* Lenovo Yoga Slim 7 15ILL9 */
+	.matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "83HM"),
+	},
+	},
+	{}
+};
+
 /*
  * On some models the EC toggles the touchpad muted LED on touchpad toggle
  * hotkey presses, but the EC does not actually disable the touchpad itself.
@@ -2185,6 +2215,8 @@ static int ideapad_check_features(struct ideapad_private *priv)
 	priv->features.touchpad_ctrl_via_ec = touchpad_ctrl_via_ec;
 	priv->features.ymc_ec_trigger =
 		ymc_ec_trigger || dmi_check_system(ymc_ec_trigger_quirk_dmi_table);
+	priv->features.fan_mode_fix =
+		fan_mode_fix || dmi_check_system(fan_mode_fix_list);
 
 	if (!read_ec_data(handle, VPCCMD_R_FAN, &val))
 		priv->features.fan_mode = true;
@@ -2517,6 +2549,28 @@ static void ideapad_acpi_remove(struct platform_device *pdev)
 	ideapad_debugfs_exit(priv);
 }
 
+static void ideapad_fan_mode_fix(struct ideapad_private *priv)
+{
+	acpi_handle handle;
+	acpi_status status;
+
+	if (!priv->features.fan_mode_fix)
+		return;
+
+	status = acpi_get_handle(NULL, IDEAPAD_EC_UPHK_PATH, &handle);
+	if (ACPI_FAILURE(status)) {
+		dev_warn(&priv->platform_device->dev, "Could not find UPHK method for fan fix\n");
+		return;
+	}
+
+	status = acpi_execute_simple_method(handle, NULL, UPHK_FAN_RESUME);
+	if (ACPI_FAILURE(status)) {
+		dev_warn(&priv->platform_device->dev, "Failed to execute UPHK fix: %s\n",
+			acpi_format_exception(status));
+		return;
+	}
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int ideapad_acpi_resume(struct device *dev)
 {
@@ -2528,6 +2582,8 @@ static int ideapad_acpi_resume(struct device *dev)
 	if (priv->dytc)
 		dytc_profile_refresh(priv);
 
+	ideapad_fan_mode_fix(priv);
+
 	return 0;
 }
 #endif
-- 
2.52.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ