From: Armin Wolf <W_Armin@gmx.de>
To: "高 俊文" <btx342@gmail.com>, platform-driver-x86@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, qby140326@gmail.com,
ilpo.jarvinen@linux.intel.com, hansg@kernel.org
Subject: Re: [BUG] Redmi Book Pro 14 2024 (TM2307): fans never spin under Linux — root cause: EC gates fan engine on OSTP byte (tested workaround)
Date: Tue, 15 Sep 2026 23:46:59 +0200 [thread overview]
Message-ID: <2d5d8f5d-2672-4a4e-b9ab-53ad49d4c212@gmx.de> (raw)
In-Reply-To: <CAL-my2=5V8Pk+R+aAoJ556-DFR-B0wnMLckRNDbAohdZvB15+Q@mail.gmail.com>
Am 15.09.26 um 14:09 schrieb 高 俊文:
> Hi,
>
> This follows up on the report from Miloš Vlku about the Redmi Book Pro 14
> 2024 (TM2307), where the fans never spin under Linux although the same
> hardware works fine under Windows:
>
> https://lkml.iu.edu/hypermail/linux/kernel/2608.1/13832.html
>
> We have now root-caused the problem on an identical machine (second
> TM2307,
> Core Ultra 7 155H) and have a one-byte, experimentally verified
> workaround.
> Summary: the EC only runs its autonomous fan engine when the OSTP "OS
> type"
> byte in its shared memory window indicates a detected host OS. Under
> Windows
> the DSDT _REG handler writes OSTP=6; under Linux nothing writes it, OSTP
> stays 0, and the EC never spins the fans. All OS-side fan paths (MIFS WMI
> fan functions, ACPI PNP0C0B fans) are separately broken on this board, so
> fans are unreachable from Linux even at 100 degC.
>
Nice work, what is the output of "cat /sys/bus/acpi/devices/PNP0C09:*/status"?
Can you share the output of "dmesg"?
> Machine / software
> ==================
>
> DMI: XIAOMI / Redmi Book Pro 14 2024 / TM2307
> CPU: Intel Core Ultra 7 155H (Meteor Lake-H)
> BIOS: XIAOMI RMAMT4B0P0A0A (06/04/2024)
> Kernel: 7.2.3-arch1-3 (bitland-mifs-wmi incl. d3666875c75e)
>
> Symptoms (all verified)
> =======================
>
> - Fans physically never spin under Linux, even with the package at
> 101 degC for minutes (verified by microphone recording: no acoustic
> change; user-confirmed silence; multiple independent load tests).
> - hwmon (bitland_mifs): fan1/2/3_input always 0, temp1 always 0.0 degC.
> - fan_boost sysfs attribute (WMI function 20): write succeeds, no
> effect.
> - No WMI fan events (26/32) ever fire (no hwmon uevents under load).
> - Writing cur_state=1 to all five PNP0C0B cooling devices: no effect.
> - acpitz thermal zone (SSDT23 TZ00) reports a constant ~26.9 degC while
> coretemp reads 56-101 degC.
> - Under Windows, fans work normally (per Miloš Vlku's dual-boot test on
> the same board).
>
> Root cause — DSDT/SSDT evidence chain
> =====================================
>
> 1) The EC's memory window and the OSTP byte
>
> Under \_SB.PC00.LPCB.Q_EC (PNP0C09):
>
> OperationRegion (ERAM, SystemMemory, 0xFE0B0300, 0x0100)
>
> Q_EC._REG (fires when EC region space becomes available) maps the OS
> version (OSYS) to an OSTP byte and writes it:
>
> OSYS 0x03E8 -> OSTP = 2 (Linux)
> OSYS 0x07D9 -> OSTP = 3 (Windows 2009)
> OSYS 0x07DC -> OSTP = 4 (Windows 2012)
> OSYS 0x07DD -> OSTP = 5 (Windows 2015)
> OSYS 0x07DF -> OSTP = 6 (Windows 2021)
>
> On this machine OSTP (ERAM offset 0x64) reads 0x00 under Linux: the
> _REG write never happens (verified by dumping the window via /dev/mem;
> the rest of the window is demonstrably live, e.g. live temperature
> fields TSR0-TSRB at offsets 0x08-0x13, exposed to Linux via the SENx
> DPTF sensors whose _TMP read these bytes directly).
>
> 2) OSTP gates the EC's autonomous fan engine — experimentally verified
>
> Writing OSTP=6 (/dev/mem, single byte) at idle, then running an
> all-core load:
>
> OSTP=0 (control): 101 -> 83 degC clamp, fans silent (no airflow)
> OSTP=6: fans audibly engage and follow the EC's own
> temperature curve; package temperature bends down
> mid-load (83 -> 70 degC) instead of plateauing
> QFAN (ERAM 0x60)=4 ("full speed" performance mode value): fans spin
> at full speed regardless of temperature
>
> After writing OSTP=6 once, fan behavior matches Windows (moderate ramp,
> full speed only near the EC's high thresholds). A systemd oneshot that
> writes OSTP=6 at boot and after resume has kept the machine cool and
> correctly fan-cooled since installation.
>
> 3) The MIFS WMI fan functions are not implemented in this firmware
>
> The MIFS WMI method is WMAA in SSDT20 (device WMID, _UID "MIFS"; _WDG
> entry for GUID B60BFB48-3E5B-49E4-A0E9-8CFFE1B3434B, object id "AA").
> Its GET (0xFA) and SET (0xFB) switches implement only functions 0x08
> (SystemPerMode), 0x0A (country/kbd, sub 5) and 0x10 (misc). The fan
> functions used by bitland-mifs-wmi fall through to
>
> Default { SGER = 0xE000 } /* unsupported, zeroed buffer */
>
> i.e. function 0x0D (WMI_FN_FAN_SPEEDS) returns an all-zero buffer
> (hwmon zeros incl. WMI_FN_CPU_THERMOMETER 0x16), and functions 0x14
> (WMI_FN_MAX_FAN_SWITCH / fan_boost) and 0x15 (WMI_FN_MAX_FAN_SPEED)
> are silently ignored — exactly the observed behavior. So this board's
> firmware is "MIFS reduced" in the same sense as the MIFS v2 machines
> discussed in Yuming Sun's series, except here the WMI method exists
> but the fan function cases are absent.
>
> 4) The ACPI fan path is gated on a device this board does not declare
>
> SSDT23 declares the five PNP0C0B fans (FAN0-FAN4) with PowerResources
> FN00-FN04. Their _ON/_OFF only set software flags CVF0-4 and call
> FNCL(), which ends in:
>
> \_SB.PC00.LPCB.UPFS (ETMD, Local0, Local1)
>
> and LPCB.UPFS (DSDT) does nothing unless
>
> If ((CondRefOf (\_SB.PC00.LPCB.H_EC) && Arg0)) ...
>
> H_EC is not declared anywhere in any table on this machine, so the
> entire ACPI fan-control path is a silent no-op. This is why writing
> cur_state=1 to the cooling devices changes nothing.
>
> 5) The ACPI thermal zone yields to the (disabled) firmware controller
>
> SSDT23 TZ00._TMP:
>
> If (!ETMD) { Return (0x0BB8) } /* constant 26.85 degC */
> Return (\_SB.PC00.LPCB.MXTP ())
>
> SSDT16 IETM._OSC sets \_TZ.ETMD = Zero when the firmware reports
> native trip-point capability (CAP1 bit0 | bit1), selecting "firmware
> manages thermals" mode. Combined with (1), the firmware never enables
> fan control and the ACPI zone never reports real heat — the kernel
> never sees a reason to act.
>
> 6) Tachometer caveat for this generation
>
> The ERAM offsets 0x69/0x6B used by the MIFS v2 fan-tach patch do
> exist here, but they do NOT live-update on TM2307: they hold stale
> values (fan1=2, fan2=0) even while the fans audibly spin. Reading
> tach on this model will need a different mechanism (or none).
>
> Proposed fix
> ============
>
> Short term (upstream): have bitland-mifs-wmi write OSTP=6 (or evaluate/
> replicate the _REG OSYS mapping) at probe time for boards where the
> firmware leaves it at 0 — ideally behind a DMI quirk. Note the pending
> DMI-matching problem reported by Miloš: this board (DMI_SYS_VENDOR
> "XIAOMI", DMI_BOARD_NAME "TM2307") matches neither "Redmi" nor "TIMI"
> entries, so any Redmi-specific quirk table needs an explicit TM2307/XIAOMI
> entry.
>
> Longer term: a hwmon pwm/fan interface for boards with the reduced
> firmware could drive QFAN (0x60) and read the SENx temperatures (ERAM
> 0x08-0x13 / TSR0-TSRB), giving Linux users real fan control on this
> generation.
>
I do not think this would really solve the problem, because any attempt by the
ACPI firmware to access the embedded controller would still result in an error.
The most important thing right now is to determine why the embedded controller
driver fails to probe.
Thanks,
Armin Wolf
> Current workaround in place (for reference):
>
> systemd oneshot service, runs at boot and after resume:
>
> python3 - <<'EOF'
> import os, mmap
> f = os.open('/dev/mem', os.O_RDWR | os.O_SYNC)
> m = mmap.mmap(f, 0x1000, offset=0xFE0B0000)
> m[0x300 + 0x64] = 6 # ERAM offset 0x64 = OSTP
> m.close()
> EOF
>
> I have full acpidumps (DSDT + all 27 SSDTs, disassembled), the ERAM
> window dumps before/during/after experiments, and the load-test
> temperature logs. Happy to provide any of these, test patches, or help
> however useful.
>
> Thanks
>
> --
> @gaojunwen
next parent reply other threads:[~2026-09-15 21:47 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CAL-my2=5V8Pk+R+aAoJ556-DFR-B0wnMLckRNDbAohdZvB15+Q@mail.gmail.com>
2026-09-15 21:46 ` Armin Wolf [this message]
2026-09-16 10:10 ` 高 俊文
2026-09-15 15:26 高 俊文
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=2d5d8f5d-2672-4a4e-b9ab-53ad49d4c212@gmx.de \
--to=w_armin@gmx.de \
--cc=btx342@gmail.com \
--cc=hansg@kernel.org \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=qby140326@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®