Skip to main content

kernel/
cpufreq.rs

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