Re: [BUG] Redmi Book Pro 14 2024 (TM2307): fans never spin under Linux — root cause: EC gates fan engine on OSTP byte (tested workaround)
From: Armin Wolf
Date: Tue Sep 15 2026 - 17:47:21 EST
Am 15.09.26 um 14:09 schrieb 高 俊文:
Hi,Nice work, what is the output of "cat /sys/bus/acpi/devices/PNP0C09:*/status"?
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.
Can you share the output of "dmesg"?
Machine / softwareI do not think this would really solve the problem, because any attempt by the
==================
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.
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