base: Fix P48 pattern and add P54 thermal module

- P48: Fix AmlSerdeValue::Package pattern (struct variant, not tuple)
- P54: Add missing thermal.rs module referenced by P44
  ThermalState with zone discovery via ACPI _TMP evaluation
This commit is contained in:
2026-05-20 22:53:08 +03:00
parent 17791421c4
commit 95bbc56f97
4 changed files with 145 additions and 1 deletions
@@ -78,7 +78,7 @@ index 00000000..8b4fd533
+ if let Ok(fst_name) = AmlName::from_str(&format!("{aml_prefix}._FST")) {
+ match ctx.aml_eval(fst_name, Vec::new()) {
+ Ok(value) => {
+ if let AmlSerdeValue::Package(elements) = value {
+ if let AmlSerdeValue::Package { contents: elements } = value {
+ if elements.len() >= 2 {
+ fan.current_level = extract_u64(&elements[1]);
+ }
@@ -0,0 +1,141 @@
diff --git a/drivers/acpid/src/thermal.rs b/drivers/acpid/src/thermal.rs
new file mode 100644
index 00000000..4614e481
--- /dev/null
+++ b/drivers/acpid/src/thermal.rs
@@ -0,0 +1,135 @@
+use acpi::aml::namespace::AmlName;
+use std::str::FromStr;
+use std::sync::RwLock;
+
+use crate::acpi::{AcpiContext, AmlEvalError};
+use amlserde::AmlSerdeValue;
+
+#[derive(Clone, Debug)]
+pub struct ThermalZone {
+ pub name: String,
+ pub temperature_raw: Option<u64>,
+}
+
+impl ThermalZone {
+ fn from_zone_eval(ctx: &AcpiContext, zone_name: &str) -> Result<Self, ThermalError> {
+ let aml_prefix = format!("\\_TZ_.{zone_name}");
+
+ let mut temp_raw = None;
+
+ if let Ok(tmp_name) = AmlName::from_str(&format!("{aml_prefix}._TMP")) {
+ match ctx.aml_eval(tmp_name, Vec::new()) {
+ Ok(value) => {
+ if let AmlSerdeValue::Integer(t) = value {
+ temp_raw = Some(t as u64);
+ }
+ }
+ Err(e) => {
+ log::debug!("Thermal zone {zone_name}: _TMP eval failed: {e:?}");
+ }
+ }
+ }
+
+ Ok(Self {
+ name: zone_name.to_owned(),
+ temperature_raw: temp_raw,
+ })
+ }
+
+ pub fn temperature_celsius(&self) -> Option<f64> {
+ self.temperature_raw.map(|t| (t as f64 - 273.15) / 10.0)
+ }
+
+ pub fn to_text(&self) -> String {
+ let mut s = String::new();
+ s.push_str(&format!("name={}\n", self.name));
+ if let Some(c) = self.temperature_celsius() {
+ s.push_str(&format!("temperature={:.1}°C\n", c));
+ } else {
+ s.push_str("temperature=na\n");
+ }
+ s
+ }
+}
+
+#[derive(Debug)]
+pub enum ThermalError {
+ EvalError(AmlEvalError),
+ NotFound,
+}
+
+impl From<AmlEvalError> for ThermalError {
+ fn from(value: AmlEvalError) -> Self {
+ ThermalError::EvalError(value)
+ }
+}
+
+pub fn discover_thermal_zones(ctx: &AcpiContext) -> Vec<ThermalZone> {
+ let mut zones = Vec::new();
+
+ let zone_names = match ctx.thermal_zone_names() {
+ Ok(names) => names,
+ Err(e) => {
+ log::debug!("Thermal zone discovery failed: {e:?}");
+ return zones;
+ }
+ };
+
+ for zone_name in zone_names {
+ match ThermalZone::from_zone_eval(ctx, &zone_name) {
+ Ok(zone) => {
+ if zone.temperature_raw.is_some() {
+ log::info!(
+ "Thermal zone discovered: {} = {:.1}°C",
+ zone.name,
+ zone.temperature_celsius().unwrap_or(0.0)
+ );
+ }
+ zones.push(zone);
+ }
+ Err(e) => {
+ log::warn!("Thermal zone {zone_name}: discovery failed: {e:?}");
+ }
+ }
+ }
+
+ zones
+}
+
+pub struct ThermalState {
+ zones: RwLock<Vec<ThermalZone>>,
+}
+
+impl ThermalState {
+ pub fn new() -> Self {
+ Self {
+ zones: RwLock::new(Vec::new()),
+ }
+ }
+
+ pub fn refresh(&self, ctx: &AcpiContext) {
+ let discovered = discover_thermal_zones(ctx);
+ if let Ok(mut zones) = self.zones.write() {
+ *zones = discovered;
+ }
+ }
+
+ pub fn zones(&self) -> Vec<ThermalZone> {
+ self.zones.read().map(|g| g.clone()).unwrap_or_default()
+ }
+
+ pub fn zone_by_name(&self, name: &str) -> Option<ThermalZone> {
+ self.zones
+ .read()
+ .ok()?
+ .iter()
+ .find(|z| z.name == name)
+ .cloned()
+ }
+}
+
+impl Default for ThermalState {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+1
View File
@@ -0,0 +1 @@
../../../local/patches/base/P54-acpid-thermal-module.patch
+2
View File
@@ -89,6 +89,8 @@ patches = [
"P42-inputd-graceful-fallback.patch",
"P43-dhcpd-requires-hard-dep.patch",
"P44-acpid-thermal-zones.patch",
# P54: Add missing thermal.rs module for P44
"P54-acpid-thermal-module.patch",
# P45: Migrate e1000d and ixgbed to MSI-X via pci_allocate_interrupt_vector
"P45-net-msix-adoption.patch",
# P46: Migrate ahcid and ac97d to MSI-X via pci_allocate_interrupt_vector