acpid: thermal zone method evaluation (_TMP/_PSV/_CRT)

Add ThermalZone handle kind to the scheme: per-zone ACPI thermal
data at /scheme/acpi/thermal/<zone>/{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.
This commit is contained in:
Red Bear OS
2026-07-22 17:30:05 +09:00
parent 7071c4529e
commit 94d1b92d91
+41
View File
@@ -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));
}