Re: [RFC PATCH 2/3] platform/x86: lenovo-wmi-other: Add Legion Go fan RPM fallback
From: Antheas Kapenekakis
Date: Sat Aug 22 2026 - 14:51:25 EST
On Fri, 21 Aug 2026 at 23:47, Aditya Dash <mradityadash@xxxxxxxxx> wrote:
>
> Some Legion Go firmware does not mark fan 1 RPM as readable in Capability
> Data, although Other Mode feature 0x04030001 returns the current RPM. As a
> result, lenovo-wmi-other hides fan1_input.
>
> When the normal VALID and GET flags are missing on a supported product,
> try one read from the Other Mode feature. Expose fan1_input as read-only
> if the read succeeds and does not return 0xffffffff. Treat a later
> 0xffffffff reply as an unavailable reading.
What is your source for 0xffffffff doing this, assuming your device
does not report it? Do you know of a device in-field that does this?
It might be preferable to quirk here or just live without rpm for the
affected bioses and have the vendor push an update and drop this
patch. Not reporting the fan speed is not the end of the world. @Mark
might be able to help here. Legion participates in fwupd, so they
should be able to fix this, at least for the Go S and Go 2 moving
forward. For the original Go, it is not the end of the world.
Antheas
> Assisted-by: Pi:gpt-5.6-sol
> Signed-off-by: Aditya Dash <mradityadash@xxxxxxxxx>
> ---
> Documentation/wmi/devices/lenovo-wmi-other.rst | 4 ++++
> drivers/platform/x86/lenovo/wmi-other.c | 14 +++++++++++++-
> 2 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/wmi/devices/lenovo-wmi-other.rst b/Documentation/wmi/devices/lenovo-wmi-other.rst
> index 75f2deaaef16..c93e9e6f3fd0 100644
> --- a/Documentation/wmi/devices/lenovo-wmi-other.rst
> +++ b/Documentation/wmi/devices/lenovo-wmi-other.rst
> @@ -56,6 +56,10 @@ On supported Legion Go models, Other Mode feature ``0x04020000`` controls
> Full Speed mode in firmware. The driver exposes it as ``pwm1_enable``. Value 0
> enables Full Speed, and value 2 returns fan control to firmware.
>
> +Some Legion Go firmware does not advertise fan 1 RPM through Capability
> +Data. In that case, the driver reads Other Mode feature ``0x04030001`` for
> +``fan1_input``. Value ``0xffffffff`` means that RPM is unavailable.
> +
> LENOVO_CAPABILITY_DATA_01
> -------------------------
>
> diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86/lenovo/wmi-other.c
> index c180933e1d18..b4be7739b243 100644
> --- a/drivers/platform/x86/lenovo/wmi-other.c
> +++ b/drivers/platform/x86/lenovo/wmi-other.c
> @@ -98,6 +98,7 @@ enum lwmi_feature_id_psu {
> #define LWMI_FAN_ID(x) ((x) + LWMI_FAN_ID_BASE)
>
> #define LWMI_FAN_DIV 100
> +#define LWMI_FAN_RPM_NORMAL_SUPPORT (LWMI_SUPP_VALID | LWMI_SUPP_GET)
>
> #define LWMI_CHARGE_BEHAVIOR_DISCHARGE 0x00
> #define LWMI_CHARGE_BEHAVIOR_AUTO 0x01
> @@ -195,6 +196,7 @@ struct lwmi_om_priv {
>
> struct lwmi_fan_info fan_info[LWMI_FAN_NR];
> bool fullspeed_supported;
> + bool fan0_input_fallback;
>
> struct {
> bool capdata00_collected : 1;
> @@ -343,6 +345,8 @@ static umode_t lwmi_om_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_t
> return 0644;
>
> if (type == hwmon_fan) {
> + if (channel == 0 && priv->fan0_input_fallback && attr == hwmon_fan_input)
> + return 0444;
> if (!(priv->fan_info[channel].supported & LWMI_SUPP_VALID))
> return 0;
>
> @@ -419,6 +423,8 @@ static int lwmi_om_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
> err = lwmi_om_fan_get_set(priv, channel, &retval, false);
> if (err)
> return err;
> + if (channel == 0 && priv->fan0_input_fallback && retval == U32_MAX)
> + return -EIO;
>
> *val = retval;
> return 0;
> @@ -542,6 +548,7 @@ static const struct hwmon_chip_info lwmi_om_hwmon_chip_info = {
> */
> static void lwmi_om_hwmon_add(struct lwmi_om_priv *priv)
> {
> + u32 rpm;
> long enable;
> int i, valid;
>
> @@ -563,6 +570,11 @@ static void lwmi_om_hwmon_add(struct lwmi_om_priv *priv)
>
> priv->fullspeed_supported =
> lwmi_fan_supported() && !lwmi_om_fullspeed_get(priv, &enable);
> + priv->fan0_input_fallback =
> + lwmi_fan_supported() &&
> + (priv->fan_info[0].supported & LWMI_FAN_RPM_NORMAL_SUPPORT) !=
> + LWMI_FAN_RPM_NORMAL_SUPPORT &&
> + !lwmi_om_fan_get_set(priv, 0, &rpm, false) && rpm != U32_MAX;
>
> valid = 0;
> for (i = 0; i < LWMI_FAN_NR; i++) {
> @@ -580,7 +592,7 @@ static void lwmi_om_hwmon_add(struct lwmi_om_priv *priv)
> }
> }
>
> - if (valid == 0 && !priv->fullspeed_supported) {
> + if (valid == 0 && !priv->fullspeed_supported && !priv->fan0_input_fallback) {
> dev_warn(&priv->wdev->dev,
> "fan reporting/tuning is unsupported on this device\n");
> return;
> --
> 2.55.0
>