xref: /linux/rust/kernel/cpufreq.rs (revision 85cdaca6970028bf6f544c355c90035586836ddf)
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 
11 use 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)]
25 use crate::clk::Clk;
26 
27 use core::{
28     cell::UnsafeCell,
29     marker::PhantomData,
30     ops::{Deref, DerefMut},
31     pin::Pin,
32     ptr,
33 };
34 
35 use macros::vtable;
36 
37 /// Maximum length of CPU frequency driver's name.
38 const CPUFREQ_NAME_LEN: usize = bindings::CPUFREQ_NAME_LEN as usize;
39 
40 /// Default transition latency value in nanoseconds.
41 pub const DEFAULT_TRANSITION_LATENCY_NS: u32 = bindings::CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;
42 
43 /// CPU frequency driver flags.
44 pub 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.
68 const CPUFREQ_RELATION_L: u32 = 0;
69 const CPUFREQ_RELATION_H: u32 = 1;
70 const CPUFREQ_RELATION_C: u32 = 2;
71 
72 /// Can be used with any of the above values.
73 const 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)]
79 pub 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 
88 impl 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 
102 impl 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)]
130 pub struct PolicyData(Opaque<bindings::cpufreq_policy_data>);
131 
132 impl 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)]
171 pub struct TableIndex(usize);
172 
173 impl 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 
186 impl 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)]
224 pub struct Table(Opaque<bindings::cpufreq_frequency_table>);
225 
226 impl 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`].
277 pub struct TableBox {
278     entries: Pin<KVec<bindings::cpufreq_frequency_table>>,
279 }
280 
281 impl 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 
307 impl 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)]
351 pub struct TableBuilder {
352     entries: KVec<bindings::cpufreq_frequency_table>,
353 }
354 
355 impl 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)]
420 pub struct Policy(Opaque<bindings::cpufreq_policy>);
421 
422 impl 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.
685 struct PolicyCpu<'a>(&'a mut Policy);
686 
687 impl<'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 
700 impl<'a> Deref for PolicyCpu<'a> {
701     type Target = Policy;
702 
703     fn deref(&self) -> &Self::Target {
704         self.0
705     }
706 }
707 
708 impl<'a> DerefMut for PolicyCpu<'a> {
709     fn deref_mut(&mut self) -> &mut Policy {
710         self.0
711     }
712 }
713 
714 impl<'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]
727 pub 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)]
917 pub 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.
921 unsafe 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.
926 unsafe impl<T: Driver> Send for Registration<T> {}
927 
928 impl<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.
1074 impl<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 
1410 impl<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 }
1417