[PATCH 2/2] platform/x86: bitland-mifs-wmi: Add quirk support for MECHREVO MRID6

From: Rsplwe

Date: Mon Aug 10 2026 - 00:48:50 EST


Add DMI-based quirks for MECHREVO MRID6 laptops.

The MRID6 firmware does not implement the WMI_PP_FULL_SPEED profile
and its WMI_FN_SYSTEM_AC_TYPE method always returns 0, making the AC
adapter type check unreliable.

Use machine-specific quirks to:
- map WMI_PP_PERFORMANCE as the highest performance profile
- skip the AC type validation for performance modes
- hide unsupported balanced-performance/full-speed distinctions

This allows platform profile switching to work correctly on affected
systems.

Signed-off-by: Rsplwe <i@xxxxxxxxxx>
---
drivers/platform/x86/bitland-mifs-wmi.c | 62 +++++++++++++++++++++++--
1 file changed, 57 insertions(+), 5 deletions(-)

diff --git a/drivers/platform/x86/bitland-mifs-wmi.c b/drivers/platform/x86/bitland-mifs-wmi.c
index e2652d1a1bf7..5dff4f4d923b 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>
@@ -153,6 +154,11 @@ struct bitland_fan_notify_data {
u16 speed;
};

+struct bitland_mifs_quirk {
+ bool no_full_speed;
+ bool skip_ac_type; /* EC always returns 0 for AC type */
+};
+
struct bitland_mifs_wmi_data {
struct wmi_device *wdev;
struct mutex lock; /* Protects WMI calls */
@@ -162,6 +168,28 @@ struct bitland_mifs_wmi_data {
struct device *hwmon_dev;
struct device *pp_dev;
enum platform_profile_option saved_profile;
+ struct bitland_mifs_quirk *quirk;
+};
+
+static struct bitland_mifs_quirk bitland_quirk_mrid6 = {
+ .no_full_speed = true,
+ .skip_ac_type = true,
+};
+
+static const struct dmi_system_id bitland_quirks[] = {
+ {
+ /*
+ * MECHREVO MRID6: does not implement WMI_PP_FULL_SPEED,
+ * its top profile is WMI_PP_PERFORMANCE; WMI_FN_SYSTEM_AC_TYPE
+ * always returns 0, so the adapter type check is meaningless.
+ */
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "MECHREVO"),
+ DMI_MATCH(DMI_BOARD_NAME, "MRID6"),
+ },
+ .driver_data = (void *)&bitland_quirk_mrid6,
+ },
+ {}
};

static int bitland_mifs_wmi_call(struct bitland_mifs_wmi_data *data,
@@ -209,7 +237,10 @@ static int laptop_profile_get(struct device *dev,
*profile = PLATFORM_PROFILE_BALANCED;
break;
case WMI_PP_PERFORMANCE:
- *profile = PLATFORM_PROFILE_BALANCED_PERFORMANCE;
+ if (data->quirk && data->quirk->no_full_speed)
+ *profile = PLATFORM_PROFILE_PERFORMANCE;
+ else
+ *profile = PLATFORM_PROFILE_BALANCED_PERFORMANCE;
break;
case WMI_PP_QUIET:
*profile = PLATFORM_PROFILE_LOW_POWER;
@@ -236,6 +267,10 @@ static int bitland_check_performance_capability(struct bitland_mifs_wmi_data *da
if (!power_supply_is_system_supplied())
return -EOPNOTSUPP;

+ /* Some ECs never report a meaningful AC type (always 0), skip it */
+ if (data->quirk && data->quirk->skip_ac_type)
+ return 0;
+
ret = bitland_mifs_wmi_call(data, &input, &output);
if (ret)
return ret;
@@ -267,6 +302,8 @@ static int laptop_profile_set(struct device *dev,
val = WMI_PP_BALANCED;
break;
case PLATFORM_PROFILE_BALANCED_PERFORMANCE:
+ if (data->quirk && data->quirk->no_full_speed)
+ return -EOPNOTSUPP;
ret = bitland_check_performance_capability(data);
if (ret)
return ret;
@@ -276,7 +313,10 @@ static int laptop_profile_set(struct device *dev,
ret = bitland_check_performance_capability(data);
if (ret)
return ret;
- val = WMI_PP_FULL_SPEED;
+ if (data->quirk && data->quirk->no_full_speed)
+ val = WMI_PP_PERFORMANCE;
+ else
+ val = WMI_PP_FULL_SPEED;
break;
default:
return -EOPNOTSUPP;
@@ -289,11 +329,17 @@ static int laptop_profile_set(struct device *dev,

static int platform_profile_probe(void *drvdata, unsigned long *choices)
{
+ struct bitland_mifs_wmi_data *data = drvdata;
+
set_bit(PLATFORM_PROFILE_LOW_POWER, choices);
set_bit(PLATFORM_PROFILE_BALANCED, choices);
- set_bit(PLATFORM_PROFILE_BALANCED_PERFORMANCE, choices);
- set_bit(PLATFORM_PROFILE_PERFORMANCE, choices);
-
+ if (data->quirk && data->quirk->no_full_speed) {
+ /* No separate balanced-performance tier; performance is the top mode */
+ set_bit(PLATFORM_PROFILE_PERFORMANCE, choices);
+ } else {
+ set_bit(PLATFORM_PROFILE_BALANCED_PERFORMANCE, choices);
+ set_bit(PLATFORM_PROFILE_PERFORMANCE, choices);
+ }
return 0;
}

@@ -815,6 +861,7 @@ static int bitland_mifs_wmi_probe(struct wmi_device *wdev, const void *context)
.default_label = ":" LED_FUNCTION_KBD_BACKLIGHT,
.devname_mandatory = true,
};
+ const struct dmi_system_id *match;
int ret;

drv_data = devm_kzalloc(&wdev->dev, sizeof(*drv_data), GFP_KERNEL);
@@ -829,6 +876,11 @@ static int bitland_mifs_wmi_probe(struct wmi_device *wdev, const void *context)

dev_set_drvdata(&wdev->dev, drv_data);

+ /* Apply machine-specific quirks */
+ match = dmi_first_match(bitland_quirks);
+ if (match && match->driver_data)
+ drv_data->quirk = match->driver_data;
+
if (dev_type == BITLAND_WMI_EVENT) {
/* Register input device for hotkeys */
drv_data->input_dev = devm_input_allocate_device(&wdev->dev);
--
2.55.0