@@ -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+
2285use core:: { marker:: PhantomData , ptr} ;
2386
2487use 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