All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: "孙 誉铭" <wolf109909@outlook.com>
Cc: "platform-driver-x86@vger.kernel.org"
	<platform-driver-x86@vger.kernel.org>,
	 "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	 Mingyou Chen <qby140326@gmail.com>, Armin Wolf <W_Armin@gmx.de>,
	 Hans de Goede <hansg@kernel.org>,
	Nabil Danial <nabildanial.93@gmail.com>
Subject: Re: [RESEND PATCH 4/5] platform/x86: bitland-mifs-wmi: drive lid switch via EC poll on Xiaomi Book Pro 14
Date: Mon, 24 Aug 2026 19:00:50 +0300 (EEST)	[thread overview]
Message-ID: <349da64e-fe09-0778-3b09-3f5edb0eebe4@linux.intel.com> (raw)
In-Reply-To: <20260728180944.51356-5-wolf109909@outlook.com>

[-- Attachment #1: Type: text/plain, Size: 8067 bytes --]

On Tue, 28 Jul 2026, 孙 誉铭 wrote:

> The Xiaomi Book Pro 14 (2026, Panther Lake) ships with broken
> firmware: ECON, referenced by \_SB.PC00.LPCB.Q_EC._STA, is not defined
> in any of the 34 SSDTs the firmware loads (boot log: "Could not
> resolve symbol [\_SB.PC00.LPCB.Q_EC._STA.ECON], AE_NOT_FOUND"). The
> ACPI EC driver therefore never binds and none of the EC query handlers
> execute - including _Q0C/_Q0D which notify the PNP0C0D lid device. As
> a result closing the lid generates no SW_LID event: the screen stays
> on and keys depressed by the closed lid keep typing into the visible
> lock screen, locking the user account after repeated failed logins.
> 
> The EC itself is alive and its shared-memory window at 0xFE0B0300
> (DSDT region "ERAM") tracks the lid state bit LSTE (offset 0x14, bit
> 0). Poll it from a delayed-work item and, on a change, evaluate the
> very AML methods the EC query would have run (_Q0C/_Q0D), which update
> the GFX CLID field and notify LID0 so the button driver emits SW_LID.
> 
> Gate the quirk on both the MIFS v2 firmware variant and DMI matching
> so no other machine gets polled. Verified on the affected machine: lid
> close/open now produce proper switch events handled by systemd-logind
> (Lid closed -> suspend -> Lid opened -> resume).

So does this mean it polls it while the machine is supposed to be 
suspended?

> Signed-off-by: Yuming Sun <wolf109909@outlook.com>
> ---
>  drivers/platform/x86/bitland-mifs-wmi.c | 94 ++++++++++++++++++++++++-
>  1 file changed, 93 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/platform/x86/bitland-mifs-wmi.c b/drivers/platform/x86/bitland-mifs-wmi.c
> index 5f7c85a8..550ee981 100644
> --- a/drivers/platform/x86/bitland-mifs-wmi.c
> +++ b/drivers/platform/x86/bitland-mifs-wmi.c
> @@ -14,6 +14,7 @@
>  #include <linux/dev_printk.h>
>  #include <linux/device.h>
>  #include <linux/device/devres.h>
> +#include <linux/dmi.h>
>  #include <linux/err.h>
>  #include <linux/hwmon.h>
>  #include <linux/init.h>
> @@ -34,6 +35,7 @@
>  #include <linux/unaligned.h>
>  #include <linux/units.h>
>  #include <linux/wmi.h>
> +#include <linux/workqueue.h>
>  
>  #define DRV_NAME		"bitland-mifs-wmi"
>  #define BITLAND_MIFS_GUID	"B60BFB48-3E5B-49E4-A0E9-8CFFE1B3434B"
> @@ -161,6 +163,11 @@ struct bitland_mifs_output {
>  #define MIFS_V2_EC_MEM_SIZE	0x100
>  #define MIFS_V2_EC_REG_FAN1	0x69
>  #define MIFS_V2_EC_REG_FAN2	0x6B
> +#define MIFS_V2_EC_REG_LID	0x14	/* bit 0: LSTE, 1 = lid open */
> +#define MIFS_V2_EC_LID_OPEN	BIT(0)
> +
> +/* Interval for the lid-state poll; see bitland_mifs_lid_poll() */
> +#define MIFS_V2_LID_POLL_MS	250
>  
>  static u16 mifs_status(const struct bitland_mifs_output *out)
>  {
> @@ -200,6 +207,9 @@ struct bitland_mifs_wmi_data {
>  	bool profile_valid;
>  	bool is_v2;	/* MIFS v2 firmware: QFAN perf-mode codes */
>  	u8 __iomem *ec_mem;	/* v2 EC shared-memory window */
> +	struct delayed_work lid_work;
> +	u8 last_lid;
> +	bool lid_quirk;
>  };
>  
>  static int bitland_mifs_wmi_call(struct bitland_mifs_wmi_data *data,
> @@ -390,6 +400,9 @@ static int bitland_mifs_wmi_suspend(struct device *dev)
>  	if (!data->pp_dev)
>  		return 0;
>  
> +	if (data->lid_quirk)
> +		cancel_delayed_work_sync(&data->lid_work);
> +
>  	/*
>  	 * Never abort suspend: some firmware revisions answer the perf-mode
>  	 * query with values this driver cannot map, or fail the call
> @@ -410,6 +423,11 @@ static int bitland_mifs_wmi_resume(struct device *dev)
>  	if (!data->pp_dev)
>  		return 0;
>  
> +	if (data->lid_quirk) {
> +		data->last_lid = 0xff;

Magic literal.

> +		schedule_delayed_work(&data->lid_work, 0);
> +	}
> +
>  	if (!data->profile_valid)
>  		return 0;
>  
> @@ -549,6 +567,57 @@ static const struct hwmon_chip_info laptop_chip_info = {
>  	.info = laptop_hwmon_info,
>  };
>  
> +/*
> + * Lid switch quirk (Xiaomi Book Pro 14 2026):
> + *
> + * The firmware of this machine never defines ECON, which is referenced
> + * by \_SB.PC00.LPCB.Q_EC._STA, so the ACPI EC driver never binds and
> + * none of the EC query handlers run. This kills the lid events
> + * (_Q0C/_Q0D) as well as every other EC-driven event. Poll the lid
> + * state bit (LSTE) in the EC shared-memory window and, on a change,
> + * evaluate the very AML methods the EC query would have run: they
> + * update the GFX CLID field and notify the PNP0C0D lid device, which
> + * makes the button driver emit the SW_LID event.
> + */
> +#define MIFS_LID_CLOSE_METHOD	"\\_SB.PC00.LPCB.Q_EC._Q0C"
> +#define MIFS_LID_OPEN_METHOD	"\\_SB.PC00.LPCB.Q_EC._Q0D"
> +
> +static void bitland_mifs_lid_poll(struct work_struct *work)
> +{
> +	struct bitland_mifs_wmi_data *data =
> +		container_of(to_delayed_work(work), struct bitland_mifs_wmi_data,
> +			     lid_work);
> +	u8 lid;
> +
> +	lid = readb(data->ec_mem + MIFS_V2_EC_REG_LID) & MIFS_V2_EC_LID_OPEN;
> +	if (lid != data->last_lid && data->last_lid != 0xff) {

Please name the literal properly, you're clearly meaning something with 
it.

> +		acpi_status status;
> +		acpi_string method = (acpi_string)(lid ? MIFS_LID_OPEN_METHOD :
> +						    MIFS_LID_CLOSE_METHOD);
> +
> +		status = acpi_evaluate_object(NULL, method, NULL, NULL);
> +		if (ACPI_FAILURE(status))
> +			dev_warn(&data->wdev->dev,
> +				 "lid %s AML failed: %s\n",
> +				 lid ? "open" : "close",
> +				 acpi_format_exception(status));

So if acpi failed, you still write ->last_lid?

> +	}
> +	data->last_lid = lid;
> +
> +	schedule_delayed_work(&data->lid_work,
> +			      msecs_to_jiffies(MIFS_V2_LID_POLL_MS));
> +}
> +
> +static const struct dmi_system_id bitland_mifs_lid_quirk_table[] = {
> +	{
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "XIAOMI"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Xiaomi Book Pro 14"),
> +		},
> +	},
> +	{ }
> +};
> +
>  static int laptop_kbd_led_set(struct led_classdev *led_cdev,
>  			      enum led_brightness value)
>  {
> @@ -843,6 +912,9 @@ static int bitland_mifs_wmi_probe(struct wmi_device *wdev, const void *context)
>  			if (!drv_data->ec_mem)
>  				dev_warn(&wdev->dev,
>  					 "cannot map EC window, fan tach unavailable\n");
> +
> +			drv_data->lid_quirk = drv_data->ec_mem &&
> +				dmi_check_system(bitland_mifs_lid_quirk_table);
>  		}
>  	}
>  
> @@ -897,9 +969,20 @@ static int bitland_mifs_wmi_probe(struct wmi_device *wdev, const void *context)
>  	if (ret)
>  		return ret;
>  
> -	return devm_add_action_or_reset(&wdev->dev,
> +	ret = devm_add_action_or_reset(&wdev->dev,
>  				       bitland_notifier_unregister,
>  				       &drv_data->notifier);
> +	if (ret)
> +		return ret;
> +
> +	if (drv_data->lid_quirk) {
> +		INIT_DELAYED_WORK(&drv_data->lid_work, bitland_mifs_lid_poll);

devm_delayed_work_autocancel() ?

> +		drv_data->last_lid = 0xff;

The literal here as well.

> +		schedule_delayed_work(&drv_data->lid_work,
> +				      msecs_to_jiffies(MIFS_V2_LID_POLL_MS));

Add include for msecs_to_jiffies().

> +	}
> +
> +	return 0;
>  }
>  
>  static void bitland_mifs_wmi_notify(struct wmi_device *wdev,
> @@ -982,6 +1065,14 @@ static void bitland_mifs_wmi_notify(struct wmi_device *wdev,
>  	}
>  }
>  
> +static void bitland_mifs_wmi_remove(struct wmi_device *wdev)
> +{
> +	struct bitland_mifs_wmi_data *data = dev_get_drvdata(&wdev->dev);
> +
> +	if (data->lid_quirk)
> +		cancel_delayed_work_sync(&data->lid_work);
> +}
> +
>  static const struct wmi_device_id bitland_mifs_wmi_id_table[] = {
>  	{ BITLAND_MIFS_GUID, (void *)BITLAND_WMI_CONTROL },
>  	{ BITLAND_EVENT_GUID, (void *)BITLAND_WMI_EVENT },
> @@ -999,6 +1090,7 @@ static struct wmi_driver bitland_mifs_wmi_driver = {
>  	.id_table = bitland_mifs_wmi_id_table,
>  	.min_event_size = sizeof(struct bitland_mifs_event),
>  	.probe = bitland_mifs_wmi_probe,
> +	.remove = bitland_mifs_wmi_remove,
>  	.notify_new = bitland_mifs_wmi_notify,
>  };
>  
> 

-- 
 i.

  reply	other threads:[~2026-08-24 16:00 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-28 18:09 [RESEND PATCH 0/5] platform/x86: bitland-mifs-wmi: MIFS v2 firmware support (Xiaomi Book Pro 14 2026) 孙 誉铭
2026-07-28 18:09 ` [RESEND PATCH 1/5] platform/x86: bitland-mifs-wmi: validate WMAA status, never abort suspend 孙 誉铭
2026-08-24 15:42   ` Ilpo Järvinen
2026-08-26 13:26     ` KentoNion
2026-08-26 13:29     ` KentoNion
2026-07-28 18:09 ` [RESEND PATCH 2/5] platform/x86: bitland-mifs-wmi: support MIFS v2 perf-mode mapping 孙 誉铭
2026-07-30 10:56   ` Mingyou Chen
2026-08-16 22:18   ` kento
2026-07-28 18:10 ` [RESEND PATCH 3/5] platform/x86: bitland-mifs-wmi: read fan tach from EC window on MIFS v2 孙 誉铭
2026-08-24 15:48   ` Ilpo Järvinen
2026-07-28 18:10 ` [RESEND PATCH 4/5] platform/x86: bitland-mifs-wmi: drive lid switch via EC poll on Xiaomi Book Pro 14 孙 誉铭
2026-08-24 16:00   ` Ilpo Järvinen [this message]
2026-08-26 13:26     ` KentoNion
2026-08-26 13:29     ` KentoNion
2026-07-28 18:10 ` [RESEND PATCH 5/5] Documentation: wmi: bitland-mifs-wmi: document MIFS v2 firmware variant 孙 誉铭
2026-07-30  9:24 ` [RESEND PATCH 0/5] platform/x86: bitland-mifs-wmi: MIFS v2 firmware support (Xiaomi Book Pro 14 2026) Armin Wolf
2026-08-26 13:26   ` KentoNion
2026-08-26 13:29   ` KentoNion
2026-08-27 22:04     ` Armin Wolf
2026-08-26 21:45 ` Armin Wolf
2026-10-07 10:53 ` Eason

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=349da64e-fe09-0778-3b09-3f5edb0eebe4@linux.intel.com \
    --to=ilpo.jarvinen@linux.intel.com \
    --cc=W_Armin@gmx.de \
    --cc=hansg@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nabildanial.93@gmail.com \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=qby140326@gmail.com \
    --cc=wolf109909@outlook.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.