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