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