kernel/
cpufreq.rs

1// SPDX-License-Identifier: GPL-2.0
2
3//! CPU frequency scaling.
4//!
5//! This module provides rust abstractions for interacting with the cpufreq subsystem.
6//!
7//! C header: [`include/linux/cpufreq.h`](srctree/include/linux/cpufreq.h)
8//!
9//! Reference: <https://docs.kernel.org/admin-guide/pm/cpufreq.html>
10
11use crate::{
12    clk::Hertz,
13    cpu::CpuId,
14    cpumask,
15    device::{Bound, Device},
16    devres,
17    error::{code::*, from_err_ptr, from_result, to_result, Result, VTABLE_DEFAULT_ERROR},
18    ffi::{c_char, c_ulong},
19    prelude::*,
20    types::ForeignOwnable,
21    types::Opaque,
22};
23
24#[cfg(CONFIG_COMMON_CLK)]
25use crate::clk::Clk;
26
27use core::{
28    cell::UnsafeCell,
29    marker::PhantomData,
30    ops::{Deref, DerefMut},
31    pin::Pin,
32    ptr,
33};
34
35use macros::vtable;
36use safety_macro::safety;
37
38/// Maximum length of CPU frequency driver's name.
39const CPUFREQ_NAME_LEN: usize = bindings::CPUFREQ_NAME_LEN as usize;
40
41/// Default transition latency value in nanoseconds.
42pub const DEFAULT_TRANSITION_LATENCY_NS: u32 = bindings::CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;
43
44/// CPU frequency driver flags.
45pub mod flags {
46    /// Driver needs to update internal limits even if frequency remains unchanged.
47    pub const NEED_UPDATE_LIMITS: u16 = 1 << 0;
48
49    /// Platform where constants like `loops_per_jiffy` are unaffected by frequency changes.
50    pub const CONST_LOOPS: u16 = 1 << 1;
51
52    /// Register driver as a thermal cooling device automatically.
53    pub const IS_COOLING_DEV: u16 = 1 << 2;
54
55    /// Supports multiple clock domains with per-policy governors in `cpu/cpuN/cpufreq/`.
56    pub const HAVE_GOVERNOR_PER_POLICY: u16 = 1 << 3;
57
58    /// Allows post-change notifications outside of the `target()` routine.
59    pub const ASYNC_NOTIFICATION: u16 = 1 << 4;
60
61    /// Ensure CPU starts at a valid frequency from the driver's freq-table.
62    pub const NEED_INITIAL_FREQ_CHECK: u16 = 1 << 5;
63
64    /// Disallow governors with `dynamic_switching` capability.
65    pub const NO_AUTO_DYNAMIC_SWITCHING: u16 = 1 << 6;
66}
67
68/// Relations from the C code.
69const CPUFREQ_RELATION_L: u32 = 0;
70const CPUFREQ_RELATION_H: u32 = 1;
71const CPUFREQ_RELATION_C: u32 = 2;
72
73/// Can be used with any of the above values.
74const CPUFREQ_RELATION_E: u32 = 1 << 2;
75
76/// CPU frequency selection relations.
77///
78/// CPU frequency selection relations, each optionally marked as "efficient".
79#[derive(Copy, Clone, Debug, Eq, PartialEq)]
80pub enum Relation {
81    /// Select the lowest frequency at or above target.
82    Low(bool),
83    /// Select the highest frequency below or at target.
84    High(bool),
85    /// Select the closest frequency to the target.
86    Close(bool),
87}
88
89impl Relation {
90    // Construct from a C-compatible `u32` value.
91    fn new(val: u32) -> Result<Self> {
92        let efficient = val & CPUFREQ_RELATION_E != 0;
93
94        Ok(match val & !CPUFREQ_RELATION_E {
95            CPUFREQ_RELATION_L => Self::Low(efficient),
96            CPUFREQ_RELATION_H => Self::High(efficient),
97            CPUFREQ_RELATION_C => Self::Close(efficient),
98            _ => return Err(EINVAL),
99        })
100    }
101}
102
103impl From<Relation> for u32 {
104    // Convert to a C-compatible `u32` value.
105    fn from(rel: Relation) -> Self {
106        let (mut val, efficient) = match rel {
107            Relation::Low(e) => (CPUFREQ_RELATION_L, e),
108            Relation::High(e) => (CPUFREQ_RELATION_H, e),
109            Relation::Close(e) => (CPUFREQ_RELATION_C, e),
110        };
111
112        if efficient {
113            val |= CPUFREQ_RELATION_E;
114        }
115
116        val
117    }
118}
119
120/// Policy data.
121///
122/// Rust abstraction for the C `struct cpufreq_policy_data`.
123///
124/// # Invariants
125///
126/// A [`PolicyData`] instance always corresponds to a valid C `struct cpufreq_policy_data`.
127///
128/// The callers must ensure that the `struct cpufreq_policy_data` is valid for access and remains
129/// valid for the lifetime of the returned reference.
130#[repr(transparent)]
131pub struct PolicyData(Opaque<bindings::cpufreq_policy_data>);
132
133impl PolicyData {
134    /// Creates a mutable reference to an existing `struct cpufreq_policy_data` pointer.
135    ///
136    /// # Safety
137    ///
138    /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime
139    /// of the returned reference.
140    #[safety{ValidWrite(ptr, "some"), Alive(ptr, "\'a")}]
141    #[inline]
142    pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy_data) -> &'a mut Self {
143        // SAFETY: Guaranteed by the safety requirements of the function.
144        //
145        // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the
146        // lifetime of the returned reference.
147        unsafe { &mut *ptr.cast() }
148    }
149
150    /// Returns a raw pointer to the underlying C `cpufreq_policy_data`.
151    #[inline]
152    pub fn as_raw(&self) -> *mut bindings::cpufreq_policy_data {
153        let this: *const Self = self;
154        this.cast_mut().cast()
155    }
156
157    /// Wrapper for `cpufreq_generic_frequency_table_verify`.
158    #[inline]
159    pub fn generic_verify(&self) -> Result {
160        // SAFETY: By the type invariant, the pointer stored in `self` is valid.
161        to_result(unsafe { bindings::cpufreq_generic_frequency_table_verify(self.as_raw()) })
162    }
163}
164
165/// The frequency table index.
166///
167/// Represents index with a frequency table.
168///
169/// # Invariants
170///
171/// The index must correspond to a valid entry in the [`Table`] it is used for.
172#[derive(Copy, Clone, PartialEq, Eq, Debug)]
173pub struct TableIndex(usize);
174
175impl TableIndex {
176    /// Creates an instance of [`TableIndex`].
177    ///
178    /// # Safety
179    ///
180    /// The caller must ensure that `index` correspond to a valid entry in the [`Table`] it is used
181    /// for.
182    #[safety{ValidNum}]
183    pub unsafe fn new(index: usize) -> Self {
184        // INVARIANT: The caller ensures that `index` correspond to a valid entry in the [`Table`].
185        Self(index)
186    }
187}
188
189impl From<TableIndex> for usize {
190    #[inline]
191    fn from(index: TableIndex) -> Self {
192        index.0
193    }
194}
195
196/// CPU frequency table.
197///
198/// Rust abstraction for the C `struct cpufreq_frequency_table`.
199///
200/// # Invariants
201///
202/// A [`Table`] instance always corresponds to a valid C `struct cpufreq_frequency_table`.
203///
204/// The callers must ensure that the `struct cpufreq_frequency_table` is valid for access and
205/// remains valid for the lifetime of the returned reference.
206///
207/// # Examples
208///
209/// The following example demonstrates how to read a frequency value from [`Table`].
210///
211/// ```
212/// use kernel::cpufreq::{Policy, TableIndex};
213///
214/// fn show_freq(policy: &Policy) -> Result {
215///     let table = policy.freq_table()?;
216///
217///     // SAFETY: Index is a valid entry in the table.
218///     let index = unsafe { TableIndex::new(0) };
219///
220///     pr_info!("The frequency at index 0 is: {:?}\n", table.freq(index)?);
221///     pr_info!("The flags at index 0 is: {}\n", table.flags(index));
222///     pr_info!("The data at index 0 is: {}\n", table.data(index));
223///     Ok(())
224/// }
225/// ```
226#[repr(transparent)]
227pub struct Table(Opaque<bindings::cpufreq_frequency_table>);
228
229impl Table {
230    /// Creates a reference to an existing C `struct cpufreq_frequency_table` pointer.
231    ///
232    /// # Safety
233    ///
234    /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime
235    /// of the returned reference.
236    #[safety{ValidRead(ptr, "some"), Alive(ptr, "\'a")}]
237    #[inline]
238    pub unsafe fn from_raw<'a>(ptr: *const bindings::cpufreq_frequency_table) -> &'a Self {
239        // SAFETY: Guaranteed by the safety requirements of the function.
240        //
241        // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the
242        // lifetime of the returned reference.
243        unsafe { &*ptr.cast() }
244    }
245
246    /// Returns the raw mutable pointer to the C `struct cpufreq_frequency_table`.
247    #[inline]
248    pub fn as_raw(&self) -> *mut bindings::cpufreq_frequency_table {
249        let this: *const Self = self;
250        this.cast_mut().cast()
251    }
252
253    /// Returns frequency at `index` in the [`Table`].
254    #[inline]
255    pub fn freq(&self, index: TableIndex) -> Result<Hertz> {
256        // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
257        // guaranteed to be valid by its safety requirements.
258        Ok(Hertz::from_khz(unsafe {
259            (*self.as_raw().add(index.into())).frequency.try_into()?
260        }))
261    }
262
263    /// Returns flags at `index` in the [`Table`].
264    #[inline]
265    pub fn flags(&self, index: TableIndex) -> u32 {
266        // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
267        // guaranteed to be valid by its safety requirements.
268        unsafe { (*self.as_raw().add(index.into())).flags }
269    }
270
271    /// Returns data at `index` in the [`Table`].
272    #[inline]
273    pub fn data(&self, index: TableIndex) -> u32 {
274        // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
275        // guaranteed to be valid by its safety requirements.
276        unsafe { (*self.as_raw().add(index.into())).driver_data }
277    }
278}
279
280/// CPU frequency table owned and pinned in memory, created from a [`TableBuilder`].
281pub struct TableBox {
282    entries: Pin<KVec<bindings::cpufreq_frequency_table>>,
283}
284
285impl TableBox {
286    /// Constructs a new [`TableBox`] from a [`KVec`] of entries.
287    ///
288    /// # Errors
289    ///
290    /// Returns `EINVAL` if the entries list is empty.
291    #[inline]
292    fn new(entries: KVec<bindings::cpufreq_frequency_table>) -> Result<Self> {
293        if entries.is_empty() {
294            return Err(EINVAL);
295        }
296
297        Ok(Self {
298            // Pin the entries to memory, since we are passing its pointer to the C code.
299            entries: Pin::new(entries),
300        })
301    }
302
303    /// Returns a raw pointer to the underlying C `cpufreq_frequency_table`.
304    #[inline]
305    fn as_raw(&self) -> *const bindings::cpufreq_frequency_table {
306        // The pointer is valid until the table gets dropped.
307        self.entries.as_ptr()
308    }
309}
310
311impl Deref for TableBox {
312    type Target = Table;
313
314    fn deref(&self) -> &Self::Target {
315        // SAFETY: The caller owns TableBox, it is safe to deref.
316        unsafe { Self::Target::from_raw(self.as_raw()) }
317    }
318}
319
320/// CPU frequency table builder.
321///
322/// This is used by the CPU frequency drivers to build a frequency table dynamically.
323///
324/// # Examples
325///
326/// The following example demonstrates how to create a CPU frequency table.
327///
328/// ```
329/// use kernel::cpufreq::{TableBuilder, TableIndex};
330/// use kernel::clk::Hertz;
331///
332/// let mut builder = TableBuilder::new();
333///
334/// // Adds few entries to the table.
335/// builder.add(Hertz::from_mhz(700), 0, 1).unwrap();
336/// builder.add(Hertz::from_mhz(800), 2, 3).unwrap();
337/// builder.add(Hertz::from_mhz(900), 4, 5).unwrap();
338/// builder.add(Hertz::from_ghz(1), 6, 7).unwrap();
339///
340/// let table = builder.to_table().unwrap();
341///
342/// // SAFETY: Index values correspond to valid entries in the table.
343/// let (index0, index2) = unsafe { (TableIndex::new(0), TableIndex::new(2)) };
344///
345/// assert_eq!(table.freq(index0), Ok(Hertz::from_mhz(700)));
346/// assert_eq!(table.flags(index0), 0);
347/// assert_eq!(table.data(index0), 1);
348///
349/// assert_eq!(table.freq(index2), Ok(Hertz::from_mhz(900)));
350/// assert_eq!(table.flags(index2), 4);
351/// assert_eq!(table.data(index2), 5);
352/// ```
353#[derive(Default)]
354#[repr(transparent)]
355pub struct TableBuilder {
356    entries: KVec<bindings::cpufreq_frequency_table>,
357}
358
359impl TableBuilder {
360    /// Creates a new instance of [`TableBuilder`].
361    #[inline]
362    pub fn new() -> Self {
363        Self {
364            entries: KVec::new(),
365        }
366    }
367
368    /// Adds a new entry to the table.
369    pub fn add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result {
370        // Adds the new entry at the end of the vector.
371        Ok(self.entries.push(
372            bindings::cpufreq_frequency_table {
373                flags,
374                driver_data,
375                frequency: freq.as_khz() as u32,
376            },
377            GFP_KERNEL,
378        )?)
379    }
380
381    /// Consumes the [`TableBuilder`] and returns [`TableBox`].
382    pub fn to_table(mut self) -> Result<TableBox> {
383        // Add last entry to the table.
384        self.add(Hertz(c_ulong::MAX), 0, 0)?;
385
386        TableBox::new(self.entries)
387    }
388}
389
390/// CPU frequency policy.
391///
392/// Rust abstraction for the C `struct cpufreq_policy`.
393///
394/// # Invariants
395///
396/// A [`Policy`] instance always corresponds to a valid C `struct cpufreq_policy`.
397///
398/// The callers must ensure that the `struct cpufreq_policy` is valid for access and remains valid
399/// for the lifetime of the returned reference.
400///
401/// # Examples
402///
403/// The following example demonstrates how to create a CPU frequency table.
404///
405/// ```
406/// use kernel::cpufreq::{DEFAULT_TRANSITION_LATENCY_NS, Policy};
407///
408/// fn update_policy(policy: &mut Policy) {
409///     policy
410///         .set_dvfs_possible_from_any_cpu(true)
411///         .set_fast_switch_possible(true)
412///         .set_transition_latency_ns(DEFAULT_TRANSITION_LATENCY_NS);
413///
414///     pr_info!("The policy details are: {:?}\n", (policy.cpu(), policy.cur()));
415/// }
416/// ```
417#[repr(transparent)]
418pub struct Policy(Opaque<bindings::cpufreq_policy>);
419
420impl Policy {
421    /// Creates a reference to an existing `struct cpufreq_policy` pointer.
422    ///
423    /// # Safety
424    ///
425    /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime
426    /// of the returned reference.
427    #[safety{ValidRead(ptr, "some"), Alive(ptr, "\'a")}]
428    #[inline]
429    pub unsafe fn from_raw<'a>(ptr: *const bindings::cpufreq_policy) -> &'a Self {
430        // SAFETY: Guaranteed by the safety requirements of the function.
431        //
432        // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the
433        // lifetime of the returned reference.
434        unsafe { &*ptr.cast() }
435    }
436
437    /// Creates a mutable reference to an existing `struct cpufreq_policy` pointer.
438    ///
439    /// # Safety
440    ///
441    /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime
442    /// of the returned reference.
443    #[safety{ValidWrite(ptr, "some"), Alive(ptr, "\'a")}]
444    #[inline]
445    pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy) -> &'a mut Self {
446        // SAFETY: Guaranteed by the safety requirements of the function.
447        //
448        // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the
449        // lifetime of the returned reference.
450        unsafe { &mut *ptr.cast() }
451    }
452
453    /// Returns a raw mutable pointer to the C `struct cpufreq_policy`.
454    #[inline]
455    fn as_raw(&self) -> *mut bindings::cpufreq_policy {
456        let this: *const Self = self;
457        this.cast_mut().cast()
458    }
459
460    #[inline]
461    fn as_ref(&self) -> &bindings::cpufreq_policy {
462        // SAFETY: By the type invariant, the pointer stored in `self` is valid.
463        unsafe { &*self.as_raw() }
464    }
465
466    #[inline]
467    fn as_mut_ref(&mut self) -> &mut bindings::cpufreq_policy {
468        // SAFETY: By the type invariant, the pointer stored in `self` is valid.
469        unsafe { &mut *self.as_raw() }
470    }
471
472    /// Returns the primary CPU for the [`Policy`].
473    #[inline]
474    pub fn cpu(&self) -> CpuId {
475        // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
476        unsafe { CpuId::from_u32_unchecked(self.as_ref().cpu) }
477    }
478
479    /// Returns the minimum frequency for the [`Policy`].
480    #[inline]
481    pub fn min(&self) -> Hertz {
482        Hertz::from_khz(self.as_ref().min as usize)
483    }
484
485    /// Set the minimum frequency for the [`Policy`].
486    #[inline]
487    pub fn set_min(&mut self, min: Hertz) -> &mut Self {
488        self.as_mut_ref().min = min.as_khz() as u32;
489        self
490    }
491
492    /// Returns the maximum frequency for the [`Policy`].
493    #[inline]
494    pub fn max(&self) -> Hertz {
495        Hertz::from_khz(self.as_ref().max as usize)
496    }
497
498    /// Set the maximum frequency for the [`Policy`].
499    #[inline]
500    pub fn set_max(&mut self, max: Hertz) -> &mut Self {
501        self.as_mut_ref().max = max.as_khz() as u32;
502        self
503    }
504
505    /// Returns the current frequency for the [`Policy`].
506    #[inline]
507    pub fn cur(&self) -> Hertz {
508        Hertz::from_khz(self.as_ref().cur as usize)
509    }
510
511    /// Returns the suspend frequency for the [`Policy`].
512    #[inline]
513    pub fn suspend_freq(&self) -> Hertz {
514        Hertz::from_khz(self.as_ref().suspend_freq as usize)
515    }
516
517    /// Sets the suspend frequency for the [`Policy`].
518    #[inline]
519    pub fn set_suspend_freq(&mut self, freq: Hertz) -> &mut Self {
520        self.as_mut_ref().suspend_freq = freq.as_khz() as u32;
521        self
522    }
523
524    /// Provides a wrapper to the generic suspend routine.
525    #[inline]
526    pub fn generic_suspend(&mut self) -> Result {
527        // SAFETY: By the type invariant, the pointer stored in `self` is valid.
528        to_result(unsafe { bindings::cpufreq_generic_suspend(self.as_mut_ref()) })
529    }
530
531    /// Provides a wrapper to the generic get routine.
532    #[inline]
533    pub fn generic_get(&self) -> Result<u32> {
534        // SAFETY: By the type invariant, the pointer stored in `self` is valid.
535        Ok(unsafe { bindings::cpufreq_generic_get(u32::from(self.cpu())) })
536    }
537
538    /// Provides a wrapper to the register with energy model using the OPP core.
539    #[cfg(CONFIG_PM_OPP)]
540    #[inline]
541    pub fn register_em_opp(&mut self) {
542        // SAFETY: By the type invariant, the pointer stored in `self` is valid.
543        unsafe { bindings::cpufreq_register_em_with_opp(self.as_mut_ref()) };
544    }
545
546    /// Gets [`cpumask::Cpumask`] for a cpufreq [`Policy`].
547    #[inline]
548    pub fn cpus(&mut self) -> &mut cpumask::Cpumask {
549        // SAFETY: The pointer to `cpus` is valid for writing and remains valid for the lifetime of
550        // the returned reference.
551        unsafe { cpumask::CpumaskVar::from_raw_mut(&mut self.as_mut_ref().cpus) }
552    }
553
554    /// Sets clock for the [`Policy`].
555    ///
556    /// # Safety
557    ///
558    /// The caller must guarantee that the returned [`Clk`] is not dropped while it is getting used
559    /// by the C code.
560    #[safety{NonDropped(clk, "used by the C code")}]
561    #[cfg(CONFIG_COMMON_CLK)]
562    pub unsafe fn set_clk(&mut self, dev: &Device, name: Option<&CStr>) -> Result<Clk> {
563        let clk = Clk::get(dev, name)?;
564        self.as_mut_ref().clk = clk.as_raw();
565        Ok(clk)
566    }
567
568    /// Allows / disallows frequency switching code to run on any CPU.
569    #[inline]
570    pub fn set_dvfs_possible_from_any_cpu(&mut self, val: bool) -> &mut Self {
571        self.as_mut_ref().dvfs_possible_from_any_cpu = val;
572        self
573    }
574
575    /// Returns if fast switching of frequencies is possible or not.
576    #[inline]
577    pub fn fast_switch_possible(&self) -> bool {
578        self.as_ref().fast_switch_possible
579    }
580
581    /// Enables / disables fast frequency switching.
582    #[inline]
583    pub fn set_fast_switch_possible(&mut self, val: bool) -> &mut Self {
584        self.as_mut_ref().fast_switch_possible = val;
585        self
586    }
587
588    /// Sets transition latency (in nanoseconds) for the [`Policy`].
589    #[inline]
590    pub fn set_transition_latency_ns(&mut self, latency_ns: u32) -> &mut Self {
591        self.as_mut_ref().cpuinfo.transition_latency = latency_ns;
592        self
593    }
594
595    /// Sets cpuinfo `min_freq`.
596    #[inline]
597    pub fn set_cpuinfo_min_freq(&mut self, min_freq: Hertz) -> &mut Self {
598        self.as_mut_ref().cpuinfo.min_freq = min_freq.as_khz() as u32;
599        self
600    }
601
602    /// Sets cpuinfo `max_freq`.
603    #[inline]
604    pub fn set_cpuinfo_max_freq(&mut self, max_freq: Hertz) -> &mut Self {
605        self.as_mut_ref().cpuinfo.max_freq = max_freq.as_khz() as u32;
606        self
607    }
608
609    /// Set `transition_delay_us`, i.e. the minimum time between successive frequency change
610    /// requests.
611    #[inline]
612    pub fn set_transition_delay_us(&mut self, transition_delay_us: u32) -> &mut Self {
613        self.as_mut_ref().transition_delay_us = transition_delay_us;
614        self
615    }
616
617    /// Returns reference to the CPU frequency [`Table`] for the [`Policy`].
618    pub fn freq_table(&self) -> Result<&Table> {
619        if self.as_ref().freq_table.is_null() {
620            return Err(EINVAL);
621        }
622
623        // SAFETY: The `freq_table` is guaranteed to be valid for reading and remains valid for the
624        // lifetime of the returned reference.
625        Ok(unsafe { Table::from_raw(self.as_ref().freq_table) })
626    }
627
628    /// Sets the CPU frequency [`Table`] for the [`Policy`].
629    ///
630    /// # Safety
631    ///
632    /// The caller must guarantee that the [`Table`] is not dropped while it is getting used by the
633    /// C code.
634    #[safety{NonDropped(table, "used by the C code")}]
635    #[inline]
636    pub unsafe fn set_freq_table(&mut self, table: &Table) -> &mut Self {
637        self.as_mut_ref().freq_table = table.as_raw();
638        self
639    }
640
641    /// Returns the [`Policy`]'s private data.
642    pub fn data<T: ForeignOwnable>(&mut self) -> Option<<T>::Borrowed<'_>> {
643        if self.as_ref().driver_data.is_null() {
644            None
645        } else {
646            // SAFETY: The data is earlier set from [`set_data`].
647            Some(unsafe { T::borrow(self.as_ref().driver_data.cast()) })
648        }
649    }
650
651    /// Sets the private data of the [`Policy`] using a foreign-ownable wrapper.
652    ///
653    /// # Errors
654    ///
655    /// Returns `EBUSY` if private data is already set.
656    fn set_data<T: ForeignOwnable>(&mut self, data: T) -> Result {
657        if self.as_ref().driver_data.is_null() {
658            // Transfer the ownership of the data to the foreign interface.
659            self.as_mut_ref().driver_data = <T as ForeignOwnable>::into_foreign(data).cast();
660            Ok(())
661        } else {
662            Err(EBUSY)
663        }
664    }
665
666    /// Clears and returns ownership of the private data.
667    fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> {
668        if self.as_ref().driver_data.is_null() {
669            None
670        } else {
671            let data = Some(
672                // SAFETY: The data is earlier set by us from [`set_data`]. It is safe to take
673                // back the ownership of the data from the foreign interface.
674                unsafe { <T as ForeignOwnable>::from_foreign(self.as_ref().driver_data.cast()) },
675            );
676            self.as_mut_ref().driver_data = ptr::null_mut();
677            data
678        }
679    }
680}
681
682/// CPU frequency policy created from a CPU number.
683///
684/// This struct represents the CPU frequency policy obtained for a specific CPU, providing safe
685/// access to the underlying `cpufreq_policy` and ensuring proper cleanup when the `PolicyCpu` is
686/// dropped.
687struct PolicyCpu<'a>(&'a mut Policy);
688
689impl<'a> PolicyCpu<'a> {
690    fn from_cpu(cpu: CpuId) -> Result<Self> {
691        // SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU.
692        let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) })?;
693
694        Ok(Self(
695            // SAFETY: The `ptr` is guaranteed to be valid and remains valid for the lifetime of
696            // the returned reference.
697            unsafe { Policy::from_raw_mut(ptr) },
698        ))
699    }
700}
701
702impl<'a> Deref for PolicyCpu<'a> {
703    type Target = Policy;
704
705    fn deref(&self) -> &Self::Target {
706        self.0
707    }
708}
709
710impl<'a> DerefMut for PolicyCpu<'a> {
711    fn deref_mut(&mut self) -> &mut Policy {
712        self.0
713    }
714}
715
716impl<'a> Drop for PolicyCpu<'a> {
717    fn drop(&mut self) {
718        // SAFETY: The underlying pointer is guaranteed to be valid for the lifetime of `self`.
719        unsafe { bindings::cpufreq_cpu_put(self.0.as_raw()) };
720    }
721}
722
723/// CPU frequency driver.
724///
725/// Implement this trait to provide a CPU frequency driver and its callbacks.
726///
727/// Reference: <https://docs.kernel.org/cpu-freq/cpu-drivers.html>
728#[vtable]
729pub trait Driver {
730    /// Driver's name.
731    const NAME: &'static CStr;
732
733    /// Driver's flags.
734    const FLAGS: u16;
735
736    /// Boost support.
737    const BOOST_ENABLED: bool;
738
739    /// Policy specific data.
740    ///
741    /// Require that `PData` implements `ForeignOwnable`. We guarantee to never move the underlying
742    /// wrapped data structure.
743    type PData: ForeignOwnable;
744
745    /// Driver's `init` callback.
746    fn init(policy: &mut Policy) -> Result<Self::PData>;
747
748    /// Driver's `exit` callback.
749    fn exit(_policy: &mut Policy, _data: Option<Self::PData>) -> Result {
750        build_error!(VTABLE_DEFAULT_ERROR)
751    }
752
753    /// Driver's `online` callback.
754    fn online(_policy: &mut Policy) -> Result {
755        build_error!(VTABLE_DEFAULT_ERROR)
756    }
757
758    /// Driver's `offline` callback.
759    fn offline(_policy: &mut Policy) -> Result {
760        build_error!(VTABLE_DEFAULT_ERROR)
761    }
762
763    /// Driver's `suspend` callback.
764    fn suspend(_policy: &mut Policy) -> Result {
765        build_error!(VTABLE_DEFAULT_ERROR)
766    }
767
768    /// Driver's `resume` callback.
769    fn resume(_policy: &mut Policy) -> Result {
770        build_error!(VTABLE_DEFAULT_ERROR)
771    }
772
773    /// Driver's `ready` callback.
774    fn ready(_policy: &mut Policy) {
775        build_error!(VTABLE_DEFAULT_ERROR)
776    }
777
778    /// Driver's `verify` callback.
779    fn verify(data: &mut PolicyData) -> Result;
780
781    /// Driver's `setpolicy` callback.
782    fn setpolicy(_policy: &mut Policy) -> Result {
783        build_error!(VTABLE_DEFAULT_ERROR)
784    }
785
786    /// Driver's `target` callback.
787    fn target(_policy: &mut Policy, _target_freq: u32, _relation: Relation) -> Result {
788        build_error!(VTABLE_DEFAULT_ERROR)
789    }
790
791    /// Driver's `target_index` callback.
792    fn target_index(_policy: &mut Policy, _index: TableIndex) -> Result {
793        build_error!(VTABLE_DEFAULT_ERROR)
794    }
795
796    /// Driver's `fast_switch` callback.
797    fn fast_switch(_policy: &mut Policy, _target_freq: u32) -> u32 {
798        build_error!(VTABLE_DEFAULT_ERROR)
799    }
800
801    /// Driver's `adjust_perf` callback.
802    fn adjust_perf(_policy: &mut Policy, _min_perf: usize, _target_perf: usize, _capacity: usize) {
803        build_error!(VTABLE_DEFAULT_ERROR)
804    }
805
806    /// Driver's `get_intermediate` callback.
807    fn get_intermediate(_policy: &mut Policy, _index: TableIndex) -> u32 {
808        build_error!(VTABLE_DEFAULT_ERROR)
809    }
810
811    /// Driver's `target_intermediate` callback.
812    fn target_intermediate(_policy: &mut Policy, _index: TableIndex) -> Result {
813        build_error!(VTABLE_DEFAULT_ERROR)
814    }
815
816    /// Driver's `get` callback.
817    fn get(_policy: &mut Policy) -> Result<u32> {
818        build_error!(VTABLE_DEFAULT_ERROR)
819    }
820
821    /// Driver's `update_limits` callback.
822    fn update_limits(_policy: &mut Policy) {
823        build_error!(VTABLE_DEFAULT_ERROR)
824    }
825
826    /// Driver's `bios_limit` callback.
827    fn bios_limit(_policy: &mut Policy, _limit: &mut u32) -> Result {
828        build_error!(VTABLE_DEFAULT_ERROR)
829    }
830
831    /// Driver's `set_boost` callback.
832    fn set_boost(_policy: &mut Policy, _state: i32) -> Result {
833        build_error!(VTABLE_DEFAULT_ERROR)
834    }
835
836    /// Driver's `register_em` callback.
837    fn register_em(_policy: &mut Policy) {
838        build_error!(VTABLE_DEFAULT_ERROR)
839    }
840}
841
842/// CPU frequency driver Registration.
843///
844/// # Examples
845///
846/// The following example demonstrates how to register a cpufreq driver.
847///
848/// ```
849/// use kernel::{
850///     cpufreq,
851///     c_str,
852///     device::{Core, Device},
853///     macros::vtable,
854///     of, platform,
855///     sync::Arc,
856/// };
857/// struct SampleDevice;
858///
859/// #[derive(Default)]
860/// struct SampleDriver;
861///
862/// #[vtable]
863/// impl cpufreq::Driver for SampleDriver {
864///     const NAME: &'static CStr = c_str!("cpufreq-sample");
865///     const FLAGS: u16 = cpufreq::flags::NEED_INITIAL_FREQ_CHECK | cpufreq::flags::IS_COOLING_DEV;
866///     const BOOST_ENABLED: bool = true;
867///
868///     type PData = Arc<SampleDevice>;
869///
870///     fn init(policy: &mut cpufreq::Policy) -> Result<Self::PData> {
871///         // Initialize here
872///         Ok(Arc::new(SampleDevice, GFP_KERNEL)?)
873///     }
874///
875///     fn exit(_policy: &mut cpufreq::Policy, _data: Option<Self::PData>) -> Result {
876///         Ok(())
877///     }
878///
879///     fn suspend(policy: &mut cpufreq::Policy) -> Result {
880///         policy.generic_suspend()
881///     }
882///
883///     fn verify(data: &mut cpufreq::PolicyData) -> Result {
884///         data.generic_verify()
885///     }
886///
887///     fn target_index(policy: &mut cpufreq::Policy, index: cpufreq::TableIndex) -> Result {
888///         // Update CPU frequency
889///         Ok(())
890///     }
891///
892///     fn get(policy: &mut cpufreq::Policy) -> Result<u32> {
893///         policy.generic_get()
894///     }
895/// }
896///
897/// impl platform::Driver for SampleDriver {
898///     type IdInfo = ();
899///     const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
900///
901///     fn probe(
902///         pdev: &platform::Device<Core>,
903///         _id_info: Option<&Self::IdInfo>,
904///     ) -> Result<Pin<KBox<Self>>> {
905///         cpufreq::Registration::<SampleDriver>::new_foreign_owned(pdev.as_ref())?;
906///         Ok(KBox::new(Self {}, GFP_KERNEL)?.into())
907///     }
908/// }
909/// ```
910#[repr(transparent)]
911pub struct Registration<T: Driver>(KBox<UnsafeCell<bindings::cpufreq_driver>>, PhantomData<T>);
912
913/// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between threads
914/// or CPUs, so it is safe to share it.
915unsafe impl<T: Driver> Sync for Registration<T> {}
916
917#[allow(clippy::non_send_fields_in_send_ty)]
918/// SAFETY: Registration with and unregistration from the cpufreq subsystem can happen from any
919/// thread.
920unsafe impl<T: Driver> Send for Registration<T> {}
921
922impl<T: Driver> Registration<T> {
923    const VTABLE: bindings::cpufreq_driver = bindings::cpufreq_driver {
924        name: Self::copy_name(T::NAME),
925        boost_enabled: T::BOOST_ENABLED,
926        flags: T::FLAGS,
927
928        // Initialize mandatory callbacks.
929        init: Some(Self::init_callback),
930        verify: Some(Self::verify_callback),
931
932        // Initialize optional callbacks based on the traits of `T`.
933        setpolicy: if T::HAS_SETPOLICY {
934            Some(Self::setpolicy_callback)
935        } else {
936            None
937        },
938        target: if T::HAS_TARGET {
939            Some(Self::target_callback)
940        } else {
941            None
942        },
943        target_index: if T::HAS_TARGET_INDEX {
944            Some(Self::target_index_callback)
945        } else {
946            None
947        },
948        fast_switch: if T::HAS_FAST_SWITCH {
949            Some(Self::fast_switch_callback)
950        } else {
951            None
952        },
953        adjust_perf: if T::HAS_ADJUST_PERF {
954            Some(Self::adjust_perf_callback)
955        } else {
956            None
957        },
958        get_intermediate: if T::HAS_GET_INTERMEDIATE {
959            Some(Self::get_intermediate_callback)
960        } else {
961            None
962        },
963        target_intermediate: if T::HAS_TARGET_INTERMEDIATE {
964            Some(Self::target_intermediate_callback)
965        } else {
966            None
967        },
968        get: if T::HAS_GET {
969            Some(Self::get_callback)
970        } else {
971            None
972        },
973        update_limits: if T::HAS_UPDATE_LIMITS {
974            Some(Self::update_limits_callback)
975        } else {
976            None
977        },
978        bios_limit: if T::HAS_BIOS_LIMIT {
979            Some(Self::bios_limit_callback)
980        } else {
981            None
982        },
983        online: if T::HAS_ONLINE {
984            Some(Self::online_callback)
985        } else {
986            None
987        },
988        offline: if T::HAS_OFFLINE {
989            Some(Self::offline_callback)
990        } else {
991            None
992        },
993        exit: if T::HAS_EXIT {
994            Some(Self::exit_callback)
995        } else {
996            None
997        },
998        suspend: if T::HAS_SUSPEND {
999            Some(Self::suspend_callback)
1000        } else {
1001            None
1002        },
1003        resume: if T::HAS_RESUME {
1004            Some(Self::resume_callback)
1005        } else {
1006            None
1007        },
1008        ready: if T::HAS_READY {
1009            Some(Self::ready_callback)
1010        } else {
1011            None
1012        },
1013        set_boost: if T::HAS_SET_BOOST {
1014            Some(Self::set_boost_callback)
1015        } else {
1016            None
1017        },
1018        register_em: if T::HAS_REGISTER_EM {
1019            Some(Self::register_em_callback)
1020        } else {
1021            None
1022        },
1023        ..pin_init::zeroed()
1024    };
1025
1026    const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] {
1027        let src = name.to_bytes_with_nul();
1028        let mut dst = [0; CPUFREQ_NAME_LEN];
1029
1030        build_assert!(src.len() <= CPUFREQ_NAME_LEN);
1031
1032        let mut i = 0;
1033        while i < src.len() {
1034            dst[i] = src[i];
1035            i += 1;
1036        }
1037
1038        dst
1039    }
1040
1041    /// Registers a CPU frequency driver with the cpufreq core.
1042    pub fn new() -> Result<Self> {
1043        // We can't use `&Self::VTABLE` directly because the cpufreq core modifies some fields in
1044        // the C `struct cpufreq_driver`, which requires a mutable reference.
1045        let mut drv = KBox::new(UnsafeCell::new(Self::VTABLE), GFP_KERNEL)?;
1046
1047        // SAFETY: `drv` is guaranteed to be valid for the lifetime of `Registration`.
1048        to_result(unsafe { bindings::cpufreq_register_driver(drv.get_mut()) })?;
1049
1050        Ok(Self(drv, PhantomData))
1051    }
1052
1053    /// Same as [`Registration::new`], but does not return a [`Registration`] instance.
1054    ///
1055    /// Instead the [`Registration`] is owned by [`devres::register`] and will be dropped, once the
1056    /// device is detached.
1057    pub fn new_foreign_owned(dev: &Device<Bound>) -> Result
1058    where
1059        T: 'static,
1060    {
1061        devres::register(dev, Self::new()?, GFP_KERNEL)
1062    }
1063}
1064
1065/// CPU frequency driver callbacks.
1066impl<T: Driver> Registration<T> {
1067    /// Driver's `init` callback.
1068    ///
1069    /// # Safety
1070    ///
1071    /// - This function may only be called from the cpufreq C infrastructure.
1072    /// - The pointer arguments must be valid pointers.
1073    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1074    unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1075        from_result(|| {
1076            // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1077            // lifetime of `policy`.
1078            let policy = unsafe { Policy::from_raw_mut(ptr) };
1079
1080            let data = T::init(policy)?;
1081            policy.set_data(data)?;
1082            Ok(0)
1083        })
1084    }
1085
1086    /// Driver's `exit` callback.
1087    ///
1088    /// # Safety
1089    ///
1090    /// - This function may only be called from the cpufreq C infrastructure.
1091    /// - The pointer arguments must be valid pointers.
1092    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1093    unsafe extern "C" fn exit_callback(ptr: *mut bindings::cpufreq_policy) {
1094        // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1095        // lifetime of `policy`.
1096        let policy = unsafe { Policy::from_raw_mut(ptr) };
1097
1098        let data = policy.clear_data();
1099        let _ = T::exit(policy, data);
1100    }
1101
1102    /// Driver's `online` callback.
1103    ///
1104    /// # Safety
1105    ///
1106    /// - This function may only be called from the cpufreq C infrastructure.
1107    /// - The pointer arguments must be valid pointers.
1108    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1109    unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1110        from_result(|| {
1111            // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1112            // lifetime of `policy`.
1113            let policy = unsafe { Policy::from_raw_mut(ptr) };
1114            T::online(policy).map(|()| 0)
1115        })
1116    }
1117
1118    /// Driver's `offline` callback.
1119    ///
1120    /// # Safety
1121    ///
1122    /// - This function may only be called from the cpufreq C infrastructure.
1123    /// - The pointer arguments must be valid pointers.
1124    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1125    unsafe extern "C" fn offline_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1126        from_result(|| {
1127            // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1128            // lifetime of `policy`.
1129            let policy = unsafe { Policy::from_raw_mut(ptr) };
1130            T::offline(policy).map(|()| 0)
1131        })
1132    }
1133
1134    /// Driver's `suspend` callback.
1135    ///
1136    /// # Safety
1137    ///
1138    /// - This function may only be called from the cpufreq C infrastructure.
1139    /// - The pointer arguments must be valid pointers.
1140    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1141    unsafe extern "C" fn suspend_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1142        from_result(|| {
1143            // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1144            // lifetime of `policy`.
1145            let policy = unsafe { Policy::from_raw_mut(ptr) };
1146            T::suspend(policy).map(|()| 0)
1147        })
1148    }
1149
1150    /// Driver's `resume` callback.
1151    ///
1152    /// # Safety
1153    ///
1154    /// - This function may only be called from the cpufreq C infrastructure.
1155    /// - The pointer arguments must be valid pointers.
1156    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1157    unsafe extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1158        from_result(|| {
1159            // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1160            // lifetime of `policy`.
1161            let policy = unsafe { Policy::from_raw_mut(ptr) };
1162            T::resume(policy).map(|()| 0)
1163        })
1164    }
1165
1166    /// Driver's `ready` callback.
1167    ///
1168    /// # Safety
1169    ///
1170    /// - This function may only be called from the cpufreq C infrastructure.
1171    /// - The pointer arguments must be valid pointers.
1172    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1173    unsafe extern "C" fn ready_callback(ptr: *mut bindings::cpufreq_policy) {
1174        // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1175        // lifetime of `policy`.
1176        let policy = unsafe { Policy::from_raw_mut(ptr) };
1177        T::ready(policy);
1178    }
1179
1180    /// Driver's `verify` callback.
1181    ///
1182    /// # Safety
1183    ///
1184    /// - This function may only be called from the cpufreq C infrastructure.
1185    /// - The pointer arguments must be valid pointers.
1186    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1187    unsafe extern "C" fn verify_callback(ptr: *mut bindings::cpufreq_policy_data) -> c_int {
1188        from_result(|| {
1189            // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1190            // lifetime of `policy`.
1191            let data = unsafe { PolicyData::from_raw_mut(ptr) };
1192            T::verify(data).map(|()| 0)
1193        })
1194    }
1195
1196    /// Driver's `setpolicy` callback.
1197    ///
1198    /// # Safety
1199    ///
1200    /// - This function may only be called from the cpufreq C infrastructure.
1201    /// - The pointer arguments must be valid pointers.
1202    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1203    unsafe extern "C" fn setpolicy_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1204        from_result(|| {
1205            // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1206            // lifetime of `policy`.
1207            let policy = unsafe { Policy::from_raw_mut(ptr) };
1208            T::setpolicy(policy).map(|()| 0)
1209        })
1210    }
1211
1212    /// Driver's `target` callback.
1213    ///
1214    /// # Safety
1215    ///
1216    /// - This function may only be called from the cpufreq C infrastructure.
1217    /// - The pointer arguments must be valid pointers.
1218    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1219    unsafe extern "C" fn target_callback(
1220        ptr: *mut bindings::cpufreq_policy,
1221        target_freq: c_uint,
1222        relation: c_uint,
1223    ) -> c_int {
1224        from_result(|| {
1225            // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1226            // lifetime of `policy`.
1227            let policy = unsafe { Policy::from_raw_mut(ptr) };
1228            T::target(policy, target_freq, Relation::new(relation)?).map(|()| 0)
1229        })
1230    }
1231
1232    /// Driver's `target_index` callback.
1233    ///
1234    /// # Safety
1235    ///
1236    /// - This function may only be called from the cpufreq C infrastructure.
1237    /// - The pointer arguments must be valid pointers.
1238    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1239    unsafe extern "C" fn target_index_callback(
1240        ptr: *mut bindings::cpufreq_policy,
1241        index: c_uint,
1242    ) -> c_int {
1243        from_result(|| {
1244            // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1245            // lifetime of `policy`.
1246            let policy = unsafe { Policy::from_raw_mut(ptr) };
1247
1248            // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1249            // frequency table.
1250            let index = unsafe { TableIndex::new(index as usize) };
1251
1252            T::target_index(policy, index).map(|()| 0)
1253        })
1254    }
1255
1256    /// Driver's `fast_switch` callback.
1257    ///
1258    /// # Safety
1259    ///
1260    /// - This function may only be called from the cpufreq C infrastructure.
1261    /// - The pointer arguments must be valid pointers.
1262    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1263    unsafe extern "C" fn fast_switch_callback(
1264        ptr: *mut bindings::cpufreq_policy,
1265        target_freq: c_uint,
1266    ) -> c_uint {
1267        // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1268        // lifetime of `policy`.
1269        let policy = unsafe { Policy::from_raw_mut(ptr) };
1270        T::fast_switch(policy, target_freq)
1271    }
1272
1273    /// Driver's `adjust_perf` callback.
1274    ///
1275    /// # Safety
1276    ///
1277    /// - This function may only be called from the cpufreq C infrastructure.
1278    #[safety{CalledBy("cpufreq C infrastructure")}]
1279    unsafe extern "C" fn adjust_perf_callback(
1280        cpu: c_uint,
1281        min_perf: c_ulong,
1282        target_perf: c_ulong,
1283        capacity: c_ulong,
1284    ) {
1285        // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1286        let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
1287
1288        if let Ok(mut policy) = PolicyCpu::from_cpu(cpu_id) {
1289            T::adjust_perf(&mut policy, min_perf, target_perf, capacity);
1290        }
1291    }
1292
1293    /// Driver's `get_intermediate` callback.
1294    ///
1295    /// # Safety
1296    ///
1297    /// - This function may only be called from the cpufreq C infrastructure.
1298    /// - The pointer arguments must be valid pointers.
1299    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1300    unsafe extern "C" fn get_intermediate_callback(
1301        ptr: *mut bindings::cpufreq_policy,
1302        index: c_uint,
1303    ) -> c_uint {
1304        // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1305        // lifetime of `policy`.
1306        let policy = unsafe { Policy::from_raw_mut(ptr) };
1307
1308        // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1309        // frequency table.
1310        let index = unsafe { TableIndex::new(index as usize) };
1311
1312        T::get_intermediate(policy, index)
1313    }
1314
1315    /// Driver's `target_intermediate` callback.
1316    ///
1317    /// # Safety
1318    ///
1319    /// - This function may only be called from the cpufreq C infrastructure.
1320    /// - The pointer arguments must be valid pointers.
1321    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1322    unsafe extern "C" fn target_intermediate_callback(
1323        ptr: *mut bindings::cpufreq_policy,
1324        index: c_uint,
1325    ) -> c_int {
1326        from_result(|| {
1327            // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1328            // lifetime of `policy`.
1329            let policy = unsafe { Policy::from_raw_mut(ptr) };
1330
1331            // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1332            // frequency table.
1333            let index = unsafe { TableIndex::new(index as usize) };
1334
1335            T::target_intermediate(policy, index).map(|()| 0)
1336        })
1337    }
1338
1339    /// Driver's `get` callback.
1340    ///
1341    /// # Safety
1342    ///
1343    /// - This function may only be called from the cpufreq C infrastructure.
1344    #[safety{CalledBy("cpufreq C infrastructure")}]
1345    unsafe extern "C" fn get_callback(cpu: c_uint) -> c_uint {
1346        // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1347        let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
1348
1349        PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
1350    }
1351
1352    /// Driver's `update_limit` callback.
1353    ///
1354    /// # Safety
1355    ///
1356    /// - This function may only be called from the cpufreq C infrastructure.
1357    /// - The pointer arguments must be valid pointers.
1358    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1359    unsafe extern "C" fn update_limits_callback(ptr: *mut bindings::cpufreq_policy) {
1360        // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1361        // lifetime of `policy`.
1362        let policy = unsafe { Policy::from_raw_mut(ptr) };
1363        T::update_limits(policy);
1364    }
1365
1366    /// Driver's `bios_limit` callback.
1367    ///
1368    /// # Safety
1369    ///
1370    /// - This function may only be called from the cpufreq C infrastructure.
1371    /// - The pointer arguments must be valid pointers.
1372    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1373    unsafe extern "C" fn bios_limit_callback(cpu: c_int, limit: *mut c_uint) -> c_int {
1374        // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1375        let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) };
1376
1377        from_result(|| {
1378            let mut policy = PolicyCpu::from_cpu(cpu_id)?;
1379
1380            // SAFETY: `limit` is guaranteed by the C code to be valid.
1381            T::bios_limit(&mut policy, &mut (unsafe { *limit })).map(|()| 0)
1382        })
1383    }
1384
1385    /// Driver's `set_boost` callback.
1386    ///
1387    /// # Safety
1388    ///
1389    /// - This function may only be called from the cpufreq C infrastructure.
1390    /// - The pointer arguments must be valid pointers.
1391    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1392    unsafe extern "C" fn set_boost_callback(
1393        ptr: *mut bindings::cpufreq_policy,
1394        state: c_int,
1395    ) -> c_int {
1396        from_result(|| {
1397            // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1398            // lifetime of `policy`.
1399            let policy = unsafe { Policy::from_raw_mut(ptr) };
1400            T::set_boost(policy, state).map(|()| 0)
1401        })
1402    }
1403
1404    /// Driver's `register_em` callback.
1405    ///
1406    /// # Safety
1407    ///
1408    /// - This function may only be called from the cpufreq C infrastructure.
1409    /// - The pointer arguments must be valid pointers.
1410    #[safety{CalledBy("cpufreq C infrastructure"), ValidPtr}]
1411    unsafe extern "C" fn register_em_callback(ptr: *mut bindings::cpufreq_policy) {
1412        // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1413        // lifetime of `policy`.
1414        let policy = unsafe { Policy::from_raw_mut(ptr) };
1415        T::register_em(policy);
1416    }
1417}
1418
1419impl<T: Driver> Drop for Registration<T> {
1420    /// Unregisters with the cpufreq core.
1421    fn drop(&mut self) {
1422        // SAFETY: `self.0` is guaranteed to be valid for the lifetime of `Registration`.
1423        unsafe { bindings::cpufreq_unregister_driver(self.0.get_mut()) };
1424    }
1425}