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