From 95bbc56f976ac9e8477e353ec070e091681e6d01 Mon Sep 17 00:00:00 2001 From: Admin Pupkin Date: Wed, 20 May 2026 22:53:08 +0300 Subject: [PATCH] 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 --- .../patches/base/P48-acpid-fan-support.patch | 2 +- .../base/P54-acpid-thermal-module.patch | 141 ++++++++++++++++++ .../core/base/P54-acpid-thermal-module.patch | 1 + recipes/core/base/recipe.toml | 2 + 4 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 local/patches/base/P54-acpid-thermal-module.patch create mode 120000 recipes/core/base/P54-acpid-thermal-module.patch diff --git a/local/patches/base/P48-acpid-fan-support.patch b/local/patches/base/P48-acpid-fan-support.patch index 4a857b916a..e1ae1bc14d 100644 --- a/local/patches/base/P48-acpid-fan-support.patch +++ b/local/patches/base/P48-acpid-fan-support.patch @@ -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]); + } diff --git a/local/patches/base/P54-acpid-thermal-module.patch b/local/patches/base/P54-acpid-thermal-module.patch new file mode 100644 index 0000000000..ec33ddcbfa --- /dev/null +++ b/local/patches/base/P54-acpid-thermal-module.patch @@ -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, ++} ++ ++impl ThermalZone { ++ fn from_zone_eval(ctx: &AcpiContext, zone_name: &str) -> Result { ++ 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 { ++ 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 for ThermalError { ++ fn from(value: AmlEvalError) -> Self { ++ ThermalError::EvalError(value) ++ } ++} ++ ++pub fn discover_thermal_zones(ctx: &AcpiContext) -> Vec { ++ 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>, ++} ++ ++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 { ++ self.zones.read().map(|g| g.clone()).unwrap_or_default() ++ } ++ ++ pub fn zone_by_name(&self, name: &str) -> Option { ++ self.zones ++ .read() ++ .ok()? ++ .iter() ++ .find(|z| z.name == name) ++ .cloned() ++ } ++} ++ ++impl Default for ThermalState { ++ fn default() -> Self { ++ Self::new() ++ } ++} diff --git a/recipes/core/base/P54-acpid-thermal-module.patch b/recipes/core/base/P54-acpid-thermal-module.patch new file mode 120000 index 0000000000..3300e7175a --- /dev/null +++ b/recipes/core/base/P54-acpid-thermal-module.patch @@ -0,0 +1 @@ +../../../local/patches/base/P54-acpid-thermal-module.patch \ No newline at end of file diff --git a/recipes/core/base/recipe.toml b/recipes/core/base/recipe.toml index b0bc668f23..49293f5d53 100644 --- a/recipes/core/base/recipe.toml +++ b/recipes/core/base/recipe.toml @@ -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