Skip to content

Commit 14f4715

Browse files
committed
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 <viresh.kumar@linaro.org>
1 parent c6af9a1 commit 14f4715

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

rust/kernel/opp.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,69 @@ use crate::{
1919
types::{ARef, AlwaysRefCounted, Opaque},
2020
};
2121

22+
#[cfg(CONFIG_CPU_FREQ)]
23+
/// Frequency table implementation.
24+
mod freq {
25+
use super::*;
26+
use crate::cpufreq;
27+
use core::ops::Deref;
28+
29+
/// OPP frequency table.
30+
///
31+
/// A [`cpufreq::Table`] created from [`Table`].
32+
pub struct FreqTable {
33+
dev: ARef<Device>,
34+
ptr: *mut bindings::cpufreq_frequency_table,
35+
}
36+
37+
impl FreqTable {
38+
/// Creates a new instance of [`FreqTable`] from [`Table`].
39+
pub(crate) fn new(table: &Table) -> Result<Self> {
40+
let mut ptr: *mut bindings::cpufreq_frequency_table = ptr::null_mut();
41+
42+
// SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety
43+
// requirements.
44+
to_result(unsafe {
45+
bindings::dev_pm_opp_init_cpufreq_table(table.dev.as_raw(), &mut ptr)
46+
})?;
47+
48+
Ok(Self {
49+
dev: table.dev.clone(),
50+
ptr,
51+
})
52+
}
53+
54+
/// Returns a reference to the underlying [`cpufreq::Table`].
55+
#[inline]
56+
fn table(&self) -> &cpufreq::Table {
57+
// SAFETY: The `ptr` is guaranteed by the C code to be valid.
58+
unsafe { cpufreq::Table::from_raw(self.ptr) }
59+
}
60+
}
61+
62+
impl Deref for FreqTable {
63+
type Target = cpufreq::Table;
64+
65+
#[inline]
66+
fn deref(&self) -> &Self::Target {
67+
self.table()
68+
}
69+
}
70+
71+
impl Drop for FreqTable {
72+
fn drop(&mut self) {
73+
// SAFETY: The pointer was created via `dev_pm_opp_init_cpufreq_table`, and is only
74+
// freed here.
75+
unsafe {
76+
bindings::dev_pm_opp_free_cpufreq_table(self.dev.as_raw(), &mut self.as_raw())
77+
};
78+
}
79+
}
80+
}
81+
82+
#[cfg(CONFIG_CPU_FREQ)]
83+
pub use freq::FreqTable;
84+
2285
use core::{marker::PhantomData, ptr};
2386

2487
use macros::vtable;
@@ -753,6 +816,13 @@ impl Table {
753816
})
754817
}
755818

819+
/// Creates [`FreqTable`] from [`Table`].
820+
#[cfg(CONFIG_CPU_FREQ)]
821+
#[inline]
822+
pub fn cpufreq_table(&mut self) -> Result<FreqTable> {
823+
FreqTable::new(self)
824+
}
825+
756826
/// Configures device with [`OPP`] matching the frequency value.
757827
#[inline]
758828
pub fn set_rate(&self, freq: Hertz) -> Result {

0 commit comments

Comments
 (0)