From 94d1b92d915d86cea70a4609994321936aa302d2 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Wed, 22 Jul 2026 17:30:05 +0900 Subject: [PATCH] acpid: thermal zone method evaluation (_TMP/_PSV/_CRT) Add ThermalZone handle kind to the scheme: per-zone ACPI thermal data at /scheme/acpi/thermal//{temperature,passive,critical}. Each path evaluates the corresponding AML method (_TMP, _PSV, _CRT) and returns the raw integer value. ThermalFileKind enum dispatches to the correct method. thermald can now read real thermal zone temperatures and thresholds instead of relying on hardcoded values. Ported from Linux drivers/acpi/thermal.c thermal_zone_device_ops. --- drivers/acpid/src/scheme.rs | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/acpid/src/scheme.rs b/drivers/acpid/src/scheme.rs index e0b2b35f54..5bdcda3253 100644 --- a/drivers/acpid/src/scheme.rs +++ b/drivers/acpid/src/scheme.rs @@ -66,6 +66,7 @@ enum HandleKind<'a> { /// thermal zones (headless QEMU, desktops) the directory /// listing is empty. Thermal, + ThermalZone { zone: String, kind: ThermalFileKind }, /// `/scheme/acpi/power` -- entries are PowerResource objects in /// the AML namespace. On laptops these are AC adapters and /// battery controllers. On desktops and QEMU the listing is @@ -120,6 +121,13 @@ enum PowerFileKind { Online, } +#[derive(Clone, Copy, Debug)] +enum ThermalFileKind { + Temperature, + Passive, + Critical, +} + #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ProcFileKind { Pss, @@ -139,6 +147,7 @@ impl HandleKind<'_> { Self::SchemeRoot => false, Self::RegisterPci => false, Self::Thermal | Self::Power | Self::Processor | Self::DmiDir | Self::PowerBatteries => true, + Self::ThermalZone { .. } => false, Self::PowerBattery { .. } | Self::PowerAdapter { .. } => false, Self::Dmi => true, Self::DmiField(_) => false, @@ -172,6 +181,7 @@ impl HandleKind<'_> { Self::Button { .. } => 2, Self::Notifications | Self::Lid | Self::ButtonDir | Self::Fan => 0, Self::FanState(_) | Self::FanSpeed(_) => 4, + Self::ThermalZone { .. } => 16, // Directories Self::TopLevel | Self::Symbols(_) | Self::Tables => 0, Self::Thermal | Self::Power | Self::Processor | Self::DmiDir => 0, @@ -407,6 +417,23 @@ impl SchemeSync for AcpiScheme<'_, '_> { ["register_pci"] => HandleKind::RegisterPci, ["tables"] => HandleKind::Tables, ["thermal"] => HandleKind::Thermal, + ["thermal", zone_name, file] => { + let zones = self.ctx.thermal_zones(); + let zone_path = format!("\\_TZ.{}", zone_name); + if !zones.contains(&zone_path) { + return Err(Error::new(ENOENT)); + } + let kind = match *file { + "temperature" => ThermalFileKind::Temperature, + "passive" => ThermalFileKind::Passive, + "critical" => ThermalFileKind::Critical, + _ => return Err(Error::new(ENOENT)), + }; + HandleKind::ThermalZone { + zone: zone_path, + kind, + } + } ["power"] => HandleKind::Power, ["dmi"] => HandleKind::Dmi, ["processor"] => HandleKind::Processor, @@ -651,6 +678,20 @@ impl SchemeSync for AcpiScheme<'_, '_> { dmi_buf = if lines.is_empty() { lines } else { format!("{lines}\n") }; dmi_buf.as_bytes() } + HandleKind::ThermalZone { zone, kind } => { + let method = match kind { + ThermalFileKind::Temperature => "_TMP", + ThermalFileKind::Passive => "_PSV", + ThermalFileKind::Critical => "_CRT", + }; + let values = self + .ctx + .evaluate_acpi_method(zone, method, &[]) + .map_err(|_| Error::new(EIO))?; + let raw = values.first().copied().unwrap_or(0); + dmi_buf = format!("{}\n", raw); + dmi_buf.as_bytes() + } HandleKind::Processor | HandleKind::DmiDir | HandleKind::Thermal | HandleKind::Power | HandleKind::PowerBatteries | HandleKind::Symbols(_) | HandleKind::RegisterPci | HandleKind::TopLevel | HandleKind::SchemeRoot | HandleKind::Lid | HandleKind::ButtonDir | HandleKind::Fan => { return Err(Error::new(EISDIR)); }