[PATCH V8 13/14] rust: Extend OPP bindings with CPU frequency table

Viresh Kumar
2025-02-06T09:29:43Z

This commit adds bindings for CPUFreq core related API.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
rust/kernel/opp.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)

diff --git a/rust/kernel/opp.rs b/rust/kernel/opp.rs
index 8028245e94aa..4030953c2001 100644
--- a/rust/kernel/opp.rs
+++ b/rust/kernel/opp.rs
@@ -16,6 +16,12 @@
types::{ARef, AlwaysRefCounted, Opaque},
};

+#[cfg(CONFIG_CPU_FREQ)]
+use crate::cpufreq;
+
+#[cfg(CONFIG_CPU_FREQ)]
+use core::ops::Deref;
+
use core::{marker::PhantomData, ptr};

use macros::vtable;
@@ -337,6 +343,56 @@ extern "C" fn config_regulators(
}
}

+/// CPU Frequency table created from OPP entries.
+#[cfg(CONFIG_CPU_FREQ)]
+pub struct FreqTable {
+ dev: ARef<Device>,
+ table: cpufreq::Table,
+}
+
+#[cfg(CONFIG_CPU_FREQ)]
+impl FreqTable {
+ /// Creates new instance of [`FreqTable`] from raw pointer.
+ fn new(table: &Table) -> Result<Self> {
+ 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(),
+ // SAFETY: The `ptr` is guaranteed by the C code to be valid.
+ table: unsafe { cpufreq::Table::from_raw(ptr) },
+ })
+ }
+
+ /// Returns reference to the underlying [`cpufreq::Table`].
+ pub fn table(&self) -> &cpufreq::Table {
+ &self.table
+ }
+}
+
+#[cfg(CONFIG_CPU_FREQ)]
+impl Deref for FreqTable {
+ type Target = cpufreq::Table;
+
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ &self.table
+ }
+}
+
+#[cfg(CONFIG_CPU_FREQ)]
+impl Drop for FreqTable {
+ fn drop(&mut self) {
+ // SAFETY: The requirements are satisfied by the existence of `Device` and its safety
+ // requirements.
+ unsafe { bindings::dev_pm_opp_free_cpufreq_table(self.dev.as_raw(), &mut self.as_raw()) };
+ }
+}
+
/// Operating performance point (OPP) table.
///
/// Wraps the kernel's `struct opp_table`.
@@ -540,6 +596,12 @@ pub fn adjust_voltage(
})
}

+ /// Create cpufreq table from OPP table.
+ #[cfg(CONFIG_CPU_FREQ)]
+ pub fn to_cpufreq_table(&mut self) -> Result<FreqTable> {
+ FreqTable::new(self)
+ }
+
/// Sets a matching OPP based on frequency.
pub fn set_rate(&self, freq: usize) -> Result<()> {
// SAFETY: The requirements are satisfied by the existence of `Device` and its safety
--
2.31.1.272.g89b43f80a514