Re: [RESEND PATCH 2/5] platform/x86: bitland-mifs-wmi: support MIFS v2 perf-mode mapping

Mingyou Chen <[email protected]> Thu, 30 Jul 2026 18:56:30 +0800
Newsgroups org.kernel.vger.platform-driver-x86,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 7/29/26 2:09 AM, 孙 誉铭 wrote:
> The MIFS v2 firmware found on e.g. the Xiaomi Book Pro 14 2026 (Intel
> Panther Lake, SSDT device "WMID" with _UID "MIFS") implements only a
> reduced WMAA command set and reports the performance mode as raw QFAN
> embedded-controller codes { 2, 3, 4, 9, 10 } instead of the v1 0..3
> enumeration. With the v1 mapping, profile_get() returns -EINVAL for
> most firmware states ("platform_profile: Failed to get profile for
> handler bitland-mifs-wmi", also reported on REDMI Book Pro 14 2025)
> and profile_set() writes values the firmware treats as no-ops, so
> power-profiles-daemon can neither read nor switch the profile;
> selecting "performance" fails outright and wedges the daemon.
>
> Detect the variant at probe time by querying the current mode: values
> outside the v1 enumeration mean v2 firmware. Map the v2 codes to
> platform profiles (2=quiet, 3=balanced, 4=speed, 9/10=extreme) and
> skip the v1-only AC-type capability probe, which does not exist on v2
> and now fails the call after the status-word check.
>
> Values verified against the laptop's SSDT WMAA method and by observing
> the EC QFAN register while switching modes.
>
> Signed-off-by: Yuming Sun <[email protected]>
> ---
>   drivers/platform/x86/bitland-mifs-wmi.c | 79 +++++++++++++++++++++++++
>   1 file changed, 79 insertions(+)
>
> diff --git a/drivers/platform/x86/bitland-mifs-wmi.c b/drivers/platform/x86/bitland-mifs-wmi.c
> index 12426d11..342dd7e1 100644
> --- a/drivers/platform/x86/bitland-mifs-wmi.c
> +++ b/drivers/platform/x86/bitland-mifs-wmi.c
> @@ -73,6 +73,21 @@ enum bitland_mifs_power_profile {
>   	WMI_PP_FULL_SPEED	= 3,
>   };
>   
> +/*
> + * MIFS v2 firmware (e.g. Xiaomi Book Pro 14 2026, SSDT "WMID" with UID
> + * "MIFS") implements a reduced WMAA command set (only function groups
> + * 0x0800/0x0a00/0x0c00/0x1000) and reports the performance mode as raw
> + * QFAN EC codes instead of the v1 0..3 enumeration. Codes 9 and 10 are
> + * the SMM-backed "extreme" modes.
> + */
> +enum bitland_mifs_v2_power_profile {
> +	WMI_V2_PP_QUIET		= 2,
> +	WMI_V2_PP_BALANCED	= 3,
> +	WMI_V2_PP_SPEED		= 4,
> +	WMI_V2_PP_EXTREME	= 9,
> +	WMI_V2_PP_EXTREME2	= 10,
> +};
> +
>   enum bitland_mifs_event_id {
>   	WMI_EVENT_RESERVED_1		= 1,
>   	WMI_EVENT_RESERVED_2		= 2,
> @@ -172,6 +187,7 @@ struct bitland_mifs_wmi_data {
>   	struct device *pp_dev;
>   	enum platform_profile_option saved_profile;
>   	bool profile_valid;
> +	bool is_v2;	/* MIFS v2 firmware: QFAN perf-mode codes */
>   };
>   
>   static int bitland_mifs_wmi_call(struct bitland_mifs_wmi_data *data,
> @@ -217,6 +233,27 @@ static int laptop_profile_get(struct device *dev,
>   	if (ret)
>   		return ret;
>   
> +	if (data->is_v2) {
> +		switch (result.data[0]) {
> +		case WMI_V2_PP_QUIET:
> +			*profile = PLATFORM_PROFILE_LOW_POWER;
> +			break;
> +		case WMI_V2_PP_BALANCED:
> +			*profile = PLATFORM_PROFILE_BALANCED;
> +			break;
> +		case WMI_V2_PP_SPEED:
> +			*profile = PLATFORM_PROFILE_BALANCED_PERFORMANCE;
> +			break;
> +		case WMI_V2_PP_EXTREME:
> +		case WMI_V2_PP_EXTREME2:
> +			*profile = PLATFORM_PROFILE_PERFORMANCE;
> +			break;
> +		default:
> +			return -EINVAL;
> +		}
> +		return 0;
> +	}
> +
>   	switch (result.data[0]) {
>   	case WMI_PP_BALANCED:
>   		*profile = PLATFORM_PROFILE_BALANCED;
> @@ -272,6 +309,28 @@ static int laptop_profile_set(struct device *dev,
>   	int ret;
>   	u8 val;
>   
> +	if (data->is_v2) {
Consider introducing an ops table. Then you can completely remove the 
is_v2 conditions.
> +		switch (profile) {
> +		case PLATFORM_PROFILE_LOW_POWER:
> +			val = WMI_V2_PP_QUIET;
> +			break;
> +		case PLATFORM_PROFILE_BALANCED:
> +			val = WMI_V2_PP_BALANCED;
> +			break;
> +		case PLATFORM_PROFILE_BALANCED_PERFORMANCE:
> +			val = WMI_V2_PP_SPEED;
> +			break;
> +		case PLATFORM_PROFILE_PERFORMANCE:
> +			val = WMI_V2_PP_EXTREME;
> +			break;
> +		default:
> +			return -EOPNOTSUPP;
> +		}
> +		input.payload[0] = val;
> +
> +		return bitland_mifs_wmi_call(data, &input, NULL);
> +	}
> +
>   	switch (profile) {
>   	case PLATFORM_PROFILE_LOW_POWER:
>   		val = WMI_PP_QUIET;
> @@ -705,6 +764,26 @@ static int bitland_mifs_wmi_probe(struct wmi_device *wdev, const void *context)
>   
>   	dev_set_drvdata(&wdev->dev, drv_data);
>   
> +	if (dev_type == BITLAND_WMI_CONTROL) {
> +		/*
> +		 * Firmware variant detection: v1 firmware reports the perf mode
> +		 * as 0..3 (enum bitland_mifs_power_profile); anything else means
> +		 * the reduced MIFS v2 command set with raw QFAN codes.
> +		 */
> +		struct bitland_mifs_input probe_in = {
> +			.operation = WMI_METHOD_GET,
> +			.function = WMI_FN_SYSTEM_PER_MODE,
> +		};
> +		struct bitland_mifs_output probe_out;
> +
> +		if (!bitland_mifs_wmi_call(drv_data, &probe_in, &probe_out) &&
> +		    probe_out.data[0] > WMI_PP_FULL_SPEED) {
If the current profile is WMI_V2_PP_QUIET or WMI_V2_PP_BALANCED, 
probe_out.data[0] > WMI_PP_FULL_SPEED would be false.
> +			drv_data->is_v2 = true;
> +			dev_info(&wdev->dev,
> +				 "MIFS v2 firmware detected (QFAN mode codes)\n");
This log message doesn't print any useful information, consider remove it.
> +		}
> +	}
> +
>   	if (dev_type == BITLAND_WMI_EVENT) {
>   		/* Register input device for hotkeys */
>   		drv_data->input_dev = devm_input_allocate_device(&wdev->dev);