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