From: Viresh Kumar Date: Tue, 7 Jan 2025 07:23:32 +0000 (+0530) Subject: rust: opp: Extend OPP abstractions with cpufreq support X-Git-Tag: v6.16-rc1~109^2~1^2~3^2~1^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=14f47156cf390606eb719da9ad1058f87af0a291;p=thirdparty%2Flinux.git rust: opp: Extend OPP abstractions with cpufreq support Extend the OPP abstractions to include support for interacting with the cpufreq core, including the ability to retrieve frequency tables from OPP table. Signed-off-by: Viresh Kumar --- diff --git a/rust/kernel/opp.rs b/rust/kernel/opp.rs index 5293d878cb55e..212555dacd45b 100644 --- a/rust/kernel/opp.rs +++ b/rust/kernel/opp.rs @@ -19,6 +19,69 @@ use crate::{ types::{ARef, AlwaysRefCounted, Opaque}, }; +#[cfg(CONFIG_CPU_FREQ)] +/// Frequency table implementation. +mod freq { + use super::*; + use crate::cpufreq; + use core::ops::Deref; + + /// OPP frequency table. + /// + /// A [`cpufreq::Table`] created from [`Table`]. + pub struct FreqTable { + dev: ARef, + ptr: *mut bindings::cpufreq_frequency_table, + } + + impl FreqTable { + /// Creates a new instance of [`FreqTable`] from [`Table`]. + pub(crate) fn new(table: &Table) -> Result { + let mut ptr: *mut bindings::cpufreq_frequency_table = ptr::null_mut(); + + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety + // requirements. + to_result(unsafe { + bindings::dev_pm_opp_init_cpufreq_table(table.dev.as_raw(), &mut ptr) + })?; + + Ok(Self { + dev: table.dev.clone(), + ptr, + }) + } + + /// Returns a reference to the underlying [`cpufreq::Table`]. + #[inline] + fn table(&self) -> &cpufreq::Table { + // SAFETY: The `ptr` is guaranteed by the C code to be valid. + unsafe { cpufreq::Table::from_raw(self.ptr) } + } + } + + impl Deref for FreqTable { + type Target = cpufreq::Table; + + #[inline] + fn deref(&self) -> &Self::Target { + self.table() + } + } + + impl Drop for FreqTable { + fn drop(&mut self) { + // SAFETY: The pointer was created via `dev_pm_opp_init_cpufreq_table`, and is only + // freed here. + unsafe { + bindings::dev_pm_opp_free_cpufreq_table(self.dev.as_raw(), &mut self.as_raw()) + }; + } + } +} + +#[cfg(CONFIG_CPU_FREQ)] +pub use freq::FreqTable; + use core::{marker::PhantomData, ptr}; use macros::vtable; @@ -753,6 +816,13 @@ impl Table { }) } + /// Creates [`FreqTable`] from [`Table`]. + #[cfg(CONFIG_CPU_FREQ)] + #[inline] + pub fn cpufreq_table(&mut self) -> Result { + FreqTable::new(self) + } + /// Configures device with [`OPP`] matching the frequency value. #[inline] pub fn set_rate(&self, freq: Hertz) -> Result {