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