xref: /linux/rust/kernel/cpufreq.rs (revision e05d9e5c8b754cc7d72acd896f5f7caf6b78a973)
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 new entry to the table.
365     pub fn add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result {
366         // Adds the new entry at the end of the vector.
367         Ok(self.entries.push(
368             bindings::cpufreq_frequency_table {
369                 flags,
370                 driver_data,
371                 frequency: freq.as_khz() as u32,
372             },
373             GFP_KERNEL,
374         )?)
375     }
376 
377     /// Consumes the [`TableBuilder`] and returns [`TableBox`].
378     pub fn to_table(mut self) -> Result<TableBox> {
379         // Add last entry to the table.
380         self.add(Hertz(c_ulong::MAX), 0, 0)?;
381 
382         TableBox::new(self.entries)
383     }
384 }
385 
386 /// CPU frequency policy.
387 ///
388 /// Rust abstraction for the C `struct cpufreq_policy`.
389 ///
390 /// # Invariants
391 ///
392 /// A [`Policy`] instance always corresponds to a valid C `struct cpufreq_policy`.
393 ///
394 /// The callers must ensure that the `struct cpufreq_policy` is valid for access and remains valid
395 /// for the lifetime of the returned reference.
396 ///
397 /// # Examples
398 ///
399 /// The following example demonstrates how to create a CPU frequency table.
400 ///
401 /// ```
402 /// use kernel::cpufreq::{DEFAULT_TRANSITION_LATENCY_NS, Policy};
403 ///
404 /// fn update_policy(policy: &mut Policy) {
405 ///     policy
406 ///         .set_dvfs_possible_from_any_cpu(true)
407 ///         .set_fast_switch_possible(true)
408 ///         .set_transition_latency_ns(DEFAULT_TRANSITION_LATENCY_NS);
409 ///
410 ///     pr_info!("The policy details are: {:?}\n", (policy.cpu(), policy.cur()));
411 /// }
412 /// ```
413 #[repr(transparent)]
414 pub struct Policy(Opaque<bindings::cpufreq_policy>);
415 
416 impl Policy {
417     /// Creates a reference to an existing `struct cpufreq_policy` pointer.
418     ///
419     /// # Safety
420     ///
421     /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime
422     /// of the returned reference.
423     #[inline]
424     pub unsafe fn from_raw<'a>(ptr: *const bindings::cpufreq_policy) -> &'a Self {
425         // SAFETY: Guaranteed by the safety requirements of the function.
426         //
427         // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the
428         // lifetime of the returned reference.
429         unsafe { &*ptr.cast() }
430     }
431 
432     /// Creates a mutable reference to an existing `struct cpufreq_policy` pointer.
433     ///
434     /// # Safety
435     ///
436     /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime
437     /// of the returned reference.
438     #[inline]
439     pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy) -> &'a mut Self {
440         // SAFETY: Guaranteed by the safety requirements of the function.
441         //
442         // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the
443         // lifetime of the returned reference.
444         unsafe { &mut *ptr.cast() }
445     }
446 
447     /// Returns a raw mutable pointer to the C `struct cpufreq_policy`.
448     #[inline]
449     fn as_raw(&self) -> *mut bindings::cpufreq_policy {
450         let this: *const Self = self;
451         this.cast_mut().cast()
452     }
453 
454     #[inline]
455     fn as_ref(&self) -> &bindings::cpufreq_policy {
456         // SAFETY: By the type invariant, the pointer stored in `self` is valid.
457         unsafe { &*self.as_raw() }
458     }
459 
460     #[inline]
461     fn as_mut_ref(&mut self) -> &mut bindings::cpufreq_policy {
462         // SAFETY: By the type invariant, the pointer stored in `self` is valid.
463         unsafe { &mut *self.as_raw() }
464     }
465 
466     /// Returns the primary CPU for the [`Policy`].
467     #[inline]
468     pub fn cpu(&self) -> CpuId {
469         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
470         unsafe { CpuId::from_u32_unchecked(self.as_ref().cpu) }
471     }
472 
473     /// Returns the minimum frequency for the [`Policy`].
474     #[inline]
475     pub fn min(&self) -> Hertz {
476         Hertz::from_khz(self.as_ref().min as usize)
477     }
478 
479     /// Set the minimum frequency for the [`Policy`].
480     #[inline]
481     pub fn set_min(&mut self, min: Hertz) -> &mut Self {
482         self.as_mut_ref().min = min.as_khz() as u32;
483         self
484     }
485 
486     /// Returns the maximum frequency for the [`Policy`].
487     #[inline]
488     pub fn max(&self) -> Hertz {
489         Hertz::from_khz(self.as_ref().max as usize)
490     }
491 
492     /// Set the maximum frequency for the [`Policy`].
493     #[inline]
494     pub fn set_max(&mut self, max: Hertz) -> &mut Self {
495         self.as_mut_ref().max = max.as_khz() as u32;
496         self
497     }
498 
499     /// Returns the current frequency for the [`Policy`].
500     #[inline]
501     pub fn cur(&self) -> Hertz {
502         Hertz::from_khz(self.as_ref().cur as usize)
503     }
504 
505     /// Returns the suspend frequency for the [`Policy`].
506     #[inline]
507     pub fn suspend_freq(&self) -> Hertz {
508         Hertz::from_khz(self.as_ref().suspend_freq as usize)
509     }
510 
511     /// Sets the suspend frequency for the [`Policy`].
512     #[inline]
513     pub fn set_suspend_freq(&mut self, freq: Hertz) -> &mut Self {
514         self.as_mut_ref().suspend_freq = freq.as_khz() as u32;
515         self
516     }
517 
518     /// Provides a wrapper to the generic suspend routine.
519     #[inline]
520     pub fn generic_suspend(&mut self) -> Result {
521         // SAFETY: By the type invariant, the pointer stored in `self` is valid.
522         to_result(unsafe { bindings::cpufreq_generic_suspend(self.as_mut_ref()) })
523     }
524 
525     /// Provides a wrapper to the generic get routine.
526     #[inline]
527     pub fn generic_get(&self) -> Result<u32> {
528         // SAFETY: By the type invariant, the pointer stored in `self` is valid.
529         Ok(unsafe { bindings::cpufreq_generic_get(u32::from(self.cpu())) })
530     }
531 
532     /// Provides a wrapper to the register with energy model using the OPP core.
533     #[cfg(CONFIG_PM_OPP)]
534     #[inline]
535     pub fn register_em_opp(&mut self) {
536         // SAFETY: By the type invariant, the pointer stored in `self` is valid.
537         unsafe { bindings::cpufreq_register_em_with_opp(self.as_mut_ref()) };
538     }
539 
540     /// Gets [`cpumask::Cpumask`] for a cpufreq [`Policy`].
541     #[inline]
542     pub fn cpus(&mut self) -> &mut cpumask::Cpumask {
543         // SAFETY: The pointer to `cpus` is valid for writing and remains valid for the lifetime of
544         // the returned reference.
545         unsafe { cpumask::CpumaskVar::from_raw_mut(&mut self.as_mut_ref().cpus) }
546     }
547 
548     /// Sets clock for the [`Policy`].
549     ///
550     /// # Safety
551     ///
552     /// The caller must guarantee that the returned [`Clk`] is not dropped while it is getting used
553     /// by the C code.
554     #[cfg(CONFIG_COMMON_CLK)]
555     pub unsafe fn set_clk(&mut self, dev: &Device, name: Option<&CStr>) -> Result<Clk> {
556         let clk = Clk::get(dev, name)?;
557         self.as_mut_ref().clk = clk.as_raw();
558         Ok(clk)
559     }
560 
561     /// Allows / disallows frequency switching code to run on any CPU.
562     #[inline]
563     pub fn set_dvfs_possible_from_any_cpu(&mut self, val: bool) -> &mut Self {
564         self.as_mut_ref().dvfs_possible_from_any_cpu = val;
565         self
566     }
567 
568     /// Returns if fast switching of frequencies is possible or not.
569     #[inline]
570     pub fn fast_switch_possible(&self) -> bool {
571         self.as_ref().fast_switch_possible
572     }
573 
574     /// Enables / disables fast frequency switching.
575     #[inline]
576     pub fn set_fast_switch_possible(&mut self, val: bool) -> &mut Self {
577         self.as_mut_ref().fast_switch_possible = val;
578         self
579     }
580 
581     /// Sets transition latency (in nanoseconds) for the [`Policy`].
582     #[inline]
583     pub fn set_transition_latency_ns(&mut self, latency_ns: u32) -> &mut Self {
584         self.as_mut_ref().cpuinfo.transition_latency = latency_ns;
585         self
586     }
587 
588     /// Sets cpuinfo `min_freq`.
589     #[inline]
590     pub fn set_cpuinfo_min_freq(&mut self, min_freq: Hertz) -> &mut Self {
591         self.as_mut_ref().cpuinfo.min_freq = min_freq.as_khz() as u32;
592         self
593     }
594 
595     /// Sets cpuinfo `max_freq`.
596     #[inline]
597     pub fn set_cpuinfo_max_freq(&mut self, max_freq: Hertz) -> &mut Self {
598         self.as_mut_ref().cpuinfo.max_freq = max_freq.as_khz() as u32;
599         self
600     }
601 
602     /// Set `transition_delay_us`, i.e. the minimum time between successive frequency change
603     /// requests.
604     #[inline]
605     pub fn set_transition_delay_us(&mut self, transition_delay_us: u32) -> &mut Self {
606         self.as_mut_ref().transition_delay_us = transition_delay_us;
607         self
608     }
609 
610     /// Returns reference to the CPU frequency [`Table`] for the [`Policy`].
611     pub fn freq_table(&self) -> Result<&Table> {
612         if self.as_ref().freq_table.is_null() {
613             return Err(EINVAL);
614         }
615 
616         // SAFETY: The `freq_table` is guaranteed to be valid for reading and remains valid for the
617         // lifetime of the returned reference.
618         Ok(unsafe { Table::from_raw(self.as_ref().freq_table) })
619     }
620 
621     /// Sets the CPU frequency [`Table`] for the [`Policy`].
622     ///
623     /// # Safety
624     ///
625     /// The caller must guarantee that the [`Table`] is not dropped while it is getting used by the
626     /// C code.
627     #[inline]
628     pub unsafe fn set_freq_table(&mut self, table: &Table) -> &mut Self {
629         self.as_mut_ref().freq_table = table.as_raw();
630         self
631     }
632 
633     /// Returns the [`Policy`]'s private data.
634     pub fn data<T: ForeignOwnable>(&mut self) -> Option<<T>::Borrowed<'_>> {
635         if self.as_ref().driver_data.is_null() {
636             None
637         } else {
638             // SAFETY: The data is earlier set from [`set_data`].
639             Some(unsafe { T::borrow(self.as_ref().driver_data.cast()) })
640         }
641     }
642 
643     /// Sets the private data of the [`Policy`] using a foreign-ownable wrapper.
644     ///
645     /// # Errors
646     ///
647     /// Returns `EBUSY` if private data is already set.
648     fn set_data<T: ForeignOwnable>(&mut self, data: T) -> Result {
649         if self.as_ref().driver_data.is_null() {
650             // Transfer the ownership of the data to the foreign interface.
651             self.as_mut_ref().driver_data = <T as ForeignOwnable>::into_foreign(data).cast();
652             Ok(())
653         } else {
654             Err(EBUSY)
655         }
656     }
657 
658     /// Clears and returns ownership of the private data.
659     fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> {
660         if self.as_ref().driver_data.is_null() {
661             None
662         } else {
663             let data = Some(
664                 // SAFETY: The data is earlier set by us from [`set_data`]. It is safe to take
665                 // back the ownership of the data from the foreign interface.
666                 unsafe { <T as ForeignOwnable>::from_foreign(self.as_ref().driver_data.cast()) },
667             );
668             self.as_mut_ref().driver_data = ptr::null_mut();
669             data
670         }
671     }
672 }
673 
674 /// CPU frequency policy created from a CPU number.
675 ///
676 /// This struct represents the CPU frequency policy obtained for a specific CPU, providing safe
677 /// access to the underlying `cpufreq_policy` and ensuring proper cleanup when the `PolicyCpu` is
678 /// dropped.
679 struct PolicyCpu<'a>(&'a mut Policy);
680 
681 impl<'a> PolicyCpu<'a> {
682     fn from_cpu(cpu: CpuId) -> Result<Self> {
683         // SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU.
684         let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) })?;
685 
686         Ok(Self(
687             // SAFETY: The `ptr` is guaranteed to be valid and remains valid for the lifetime of
688             // the returned reference.
689             unsafe { Policy::from_raw_mut(ptr) },
690         ))
691     }
692 }
693 
694 impl<'a> Deref for PolicyCpu<'a> {
695     type Target = Policy;
696 
697     fn deref(&self) -> &Self::Target {
698         self.0
699     }
700 }
701 
702 impl<'a> DerefMut for PolicyCpu<'a> {
703     fn deref_mut(&mut self) -> &mut Policy {
704         self.0
705     }
706 }
707 
708 impl<'a> Drop for PolicyCpu<'a> {
709     fn drop(&mut self) {
710         // SAFETY: The underlying pointer is guaranteed to be valid for the lifetime of `self`.
711         unsafe { bindings::cpufreq_cpu_put(self.0.as_raw()) };
712     }
713 }
714 
715 /// CPU frequency driver.
716 ///
717 /// Implement this trait to provide a CPU frequency driver and its callbacks.
718 ///
719 /// Reference: <https://docs.kernel.org/cpu-freq/cpu-drivers.html>
720 #[vtable]
721 pub trait Driver {
722     /// Driver's name.
723     const NAME: &'static CStr;
724 
725     /// Driver's flags.
726     const FLAGS: u16;
727 
728     /// Boost support.
729     const BOOST_ENABLED: bool;
730 
731     /// Policy specific data.
732     ///
733     /// Require that `PData` implements `ForeignOwnable`. We guarantee to never move the underlying
734     /// wrapped data structure.
735     type PData: ForeignOwnable;
736 
737     /// Driver's `init` callback.
738     fn init(policy: &mut Policy) -> Result<Self::PData>;
739 
740     /// Driver's `exit` callback.
741     fn exit(_policy: &mut Policy, _data: Option<Self::PData>) -> Result {
742         build_error!(VTABLE_DEFAULT_ERROR)
743     }
744 
745     /// Driver's `online` callback.
746     fn online(_policy: &mut Policy) -> Result {
747         build_error!(VTABLE_DEFAULT_ERROR)
748     }
749 
750     /// Driver's `offline` callback.
751     fn offline(_policy: &mut Policy) -> Result {
752         build_error!(VTABLE_DEFAULT_ERROR)
753     }
754 
755     /// Driver's `suspend` callback.
756     fn suspend(_policy: &mut Policy) -> Result {
757         build_error!(VTABLE_DEFAULT_ERROR)
758     }
759 
760     /// Driver's `resume` callback.
761     fn resume(_policy: &mut Policy) -> Result {
762         build_error!(VTABLE_DEFAULT_ERROR)
763     }
764 
765     /// Driver's `ready` callback.
766     fn ready(_policy: &mut Policy) {
767         build_error!(VTABLE_DEFAULT_ERROR)
768     }
769 
770     /// Driver's `verify` callback.
771     fn verify(data: &mut PolicyData) -> Result;
772 
773     /// Driver's `setpolicy` callback.
774     fn setpolicy(_policy: &mut Policy) -> Result {
775         build_error!(VTABLE_DEFAULT_ERROR)
776     }
777 
778     /// Driver's `target` callback.
779     fn target(_policy: &mut Policy, _target_freq: u32, _relation: Relation) -> Result {
780         build_error!(VTABLE_DEFAULT_ERROR)
781     }
782 
783     /// Driver's `target_index` callback.
784     fn target_index(_policy: &mut Policy, _index: TableIndex) -> Result {
785         build_error!(VTABLE_DEFAULT_ERROR)
786     }
787 
788     /// Driver's `fast_switch` callback.
789     fn fast_switch(_policy: &mut Policy, _target_freq: u32) -> u32 {
790         build_error!(VTABLE_DEFAULT_ERROR)
791     }
792 
793     /// Driver's `adjust_perf` callback.
794     fn adjust_perf(_policy: &mut Policy, _min_perf: usize, _target_perf: usize, _capacity: usize) {
795         build_error!(VTABLE_DEFAULT_ERROR)
796     }
797 
798     /// Driver's `get_intermediate` callback.
799     fn get_intermediate(_policy: &mut Policy, _index: TableIndex) -> u32 {
800         build_error!(VTABLE_DEFAULT_ERROR)
801     }
802 
803     /// Driver's `target_intermediate` callback.
804     fn target_intermediate(_policy: &mut Policy, _index: TableIndex) -> Result {
805         build_error!(VTABLE_DEFAULT_ERROR)
806     }
807 
808     /// Driver's `get` callback.
809     fn get(_policy: &mut Policy) -> Result<u32> {
810         build_error!(VTABLE_DEFAULT_ERROR)
811     }
812 
813     /// Driver's `update_limits` callback.
814     fn update_limits(_policy: &mut Policy) {
815         build_error!(VTABLE_DEFAULT_ERROR)
816     }
817 
818     /// Driver's `bios_limit` callback.
819     fn bios_limit(_policy: &mut Policy, _limit: &mut u32) -> Result {
820         build_error!(VTABLE_DEFAULT_ERROR)
821     }
822 
823     /// Driver's `set_boost` callback.
824     fn set_boost(_policy: &mut Policy, _state: i32) -> Result {
825         build_error!(VTABLE_DEFAULT_ERROR)
826     }
827 
828     /// Driver's `register_em` callback.
829     fn register_em(_policy: &mut Policy) {
830         build_error!(VTABLE_DEFAULT_ERROR)
831     }
832 }
833 
834 /// CPU frequency driver Registration.
835 ///
836 /// # Examples
837 ///
838 /// The following example demonstrates how to register a cpufreq driver.
839 ///
840 /// ```
841 /// use kernel::{
842 ///     cpufreq,
843 ///     device::{Core, Device},
844 ///     macros::vtable,
845 ///     of, platform,
846 ///     sync::Arc,
847 /// };
848 /// struct SampleDevice;
849 ///
850 /// #[derive(Default)]
851 /// struct SampleDriver;
852 ///
853 /// #[vtable]
854 /// impl cpufreq::Driver for SampleDriver {
855 ///     const NAME: &'static CStr = c"cpufreq-sample";
856 ///     const FLAGS: u16 = cpufreq::flags::NEED_INITIAL_FREQ_CHECK | cpufreq::flags::IS_COOLING_DEV;
857 ///     const BOOST_ENABLED: bool = true;
858 ///
859 ///     type PData = Arc<SampleDevice>;
860 ///
861 ///     fn init(policy: &mut cpufreq::Policy) -> Result<Self::PData> {
862 ///         // Initialize here
863 ///         Ok(Arc::new(SampleDevice, GFP_KERNEL)?)
864 ///     }
865 ///
866 ///     fn exit(_policy: &mut cpufreq::Policy, _data: Option<Self::PData>) -> Result {
867 ///         Ok(())
868 ///     }
869 ///
870 ///     fn suspend(policy: &mut cpufreq::Policy) -> Result {
871 ///         policy.generic_suspend()
872 ///     }
873 ///
874 ///     fn verify(data: &mut cpufreq::PolicyData) -> Result {
875 ///         data.generic_verify()
876 ///     }
877 ///
878 ///     fn target_index(policy: &mut cpufreq::Policy, index: cpufreq::TableIndex) -> Result {
879 ///         // Update CPU frequency
880 ///         Ok(())
881 ///     }
882 ///
883 ///     fn get(policy: &mut cpufreq::Policy) -> Result<u32> {
884 ///         policy.generic_get()
885 ///     }
886 /// }
887 ///
888 /// impl platform::Driver for SampleDriver {
889 ///     type IdInfo = ();
890 ///     const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
891 ///
892 ///     fn probe(
893 ///         pdev: &platform::Device<Core>,
894 ///         _id_info: Option<&Self::IdInfo>,
895 ///     ) -> impl PinInit<Self, Error> {
896 ///         cpufreq::Registration::<SampleDriver>::new_foreign_owned(pdev.as_ref())?;
897 ///         Ok(Self {})
898 ///     }
899 /// }
900 /// ```
901 #[repr(transparent)]
902 pub struct Registration<T: Driver>(KBox<UnsafeCell<bindings::cpufreq_driver>>, PhantomData<T>);
903 
904 /// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between threads
905 /// or CPUs, so it is safe to share it.
906 unsafe impl<T: Driver> Sync for Registration<T> {}
907 
908 #[allow(clippy::non_send_fields_in_send_ty)]
909 /// SAFETY: Registration with and unregistration from the cpufreq subsystem can happen from any
910 /// thread.
911 unsafe impl<T: Driver> Send for Registration<T> {}
912 
913 impl<T: Driver> Registration<T> {
914     const VTABLE: bindings::cpufreq_driver = bindings::cpufreq_driver {
915         name: Self::copy_name(T::NAME),
916         boost_enabled: T::BOOST_ENABLED,
917         flags: T::FLAGS,
918 
919         // Initialize mandatory callbacks.
920         init: Some(Self::init_callback),
921         verify: Some(Self::verify_callback),
922 
923         // Initialize optional callbacks based on the traits of `T`.
924         setpolicy: if T::HAS_SETPOLICY {
925             Some(Self::setpolicy_callback)
926         } else {
927             None
928         },
929         target: if T::HAS_TARGET {
930             Some(Self::target_callback)
931         } else {
932             None
933         },
934         target_index: if T::HAS_TARGET_INDEX {
935             Some(Self::target_index_callback)
936         } else {
937             None
938         },
939         fast_switch: if T::HAS_FAST_SWITCH {
940             Some(Self::fast_switch_callback)
941         } else {
942             None
943         },
944         adjust_perf: if T::HAS_ADJUST_PERF {
945             Some(Self::adjust_perf_callback)
946         } else {
947             None
948         },
949         get_intermediate: if T::HAS_GET_INTERMEDIATE {
950             Some(Self::get_intermediate_callback)
951         } else {
952             None
953         },
954         target_intermediate: if T::HAS_TARGET_INTERMEDIATE {
955             Some(Self::target_intermediate_callback)
956         } else {
957             None
958         },
959         get: if T::HAS_GET {
960             Some(Self::get_callback)
961         } else {
962             None
963         },
964         update_limits: if T::HAS_UPDATE_LIMITS {
965             Some(Self::update_limits_callback)
966         } else {
967             None
968         },
969         bios_limit: if T::HAS_BIOS_LIMIT {
970             Some(Self::bios_limit_callback)
971         } else {
972             None
973         },
974         online: if T::HAS_ONLINE {
975             Some(Self::online_callback)
976         } else {
977             None
978         },
979         offline: if T::HAS_OFFLINE {
980             Some(Self::offline_callback)
981         } else {
982             None
983         },
984         exit: if T::HAS_EXIT {
985             Some(Self::exit_callback)
986         } else {
987             None
988         },
989         suspend: if T::HAS_SUSPEND {
990             Some(Self::suspend_callback)
991         } else {
992             None
993         },
994         resume: if T::HAS_RESUME {
995             Some(Self::resume_callback)
996         } else {
997             None
998         },
999         ready: if T::HAS_READY {
1000             Some(Self::ready_callback)
1001         } else {
1002             None
1003         },
1004         set_boost: if T::HAS_SET_BOOST {
1005             Some(Self::set_boost_callback)
1006         } else {
1007             None
1008         },
1009         register_em: if T::HAS_REGISTER_EM {
1010             Some(Self::register_em_callback)
1011         } else {
1012             None
1013         },
1014         ..pin_init::zeroed()
1015     };
1016 
1017     // Always inline to optimize out error path of `build_assert`.
1018     #[inline(always)]
1019     const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] {
1020         let src = name.to_bytes_with_nul();
1021         let mut dst = [0; CPUFREQ_NAME_LEN];
1022 
1023         build_assert!(src.len() <= CPUFREQ_NAME_LEN);
1024 
1025         let mut i = 0;
1026         while i < src.len() {
1027             dst[i] = src[i];
1028             i += 1;
1029         }
1030 
1031         dst
1032     }
1033 
1034     /// Registers a CPU frequency driver with the cpufreq core.
1035     pub fn new() -> Result<Self> {
1036         // We can't use `&Self::VTABLE` directly because the cpufreq core modifies some fields in
1037         // the C `struct cpufreq_driver`, which requires a mutable reference.
1038         let mut drv = KBox::new(UnsafeCell::new(Self::VTABLE), GFP_KERNEL)?;
1039 
1040         // SAFETY: `drv` is guaranteed to be valid for the lifetime of `Registration`.
1041         to_result(unsafe { bindings::cpufreq_register_driver(drv.get_mut()) })?;
1042 
1043         Ok(Self(drv, PhantomData))
1044     }
1045 
1046     /// Same as [`Registration::new`], but does not return a [`Registration`] instance.
1047     ///
1048     /// Instead the [`Registration`] is owned by [`devres::register`] and will be dropped, once the
1049     /// device is detached.
1050     pub fn new_foreign_owned(dev: &Device<Bound>) -> Result
1051     where
1052         T: 'static,
1053     {
1054         devres::register(dev, Self::new()?, GFP_KERNEL)
1055     }
1056 }
1057 
1058 /// CPU frequency driver callbacks.
1059 impl<T: Driver> Registration<T> {
1060     /// Driver's `init` callback.
1061     ///
1062     /// # Safety
1063     ///
1064     /// - This function may only be called from the cpufreq C infrastructure.
1065     /// - The pointer arguments must be valid pointers.
1066     unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1067         from_result(|| {
1068             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1069             // lifetime of `policy`.
1070             let policy = unsafe { Policy::from_raw_mut(ptr) };
1071 
1072             let data = T::init(policy)?;
1073             policy.set_data(data)?;
1074             Ok(0)
1075         })
1076     }
1077 
1078     /// Driver's `exit` callback.
1079     ///
1080     /// # Safety
1081     ///
1082     /// - This function may only be called from the cpufreq C infrastructure.
1083     /// - The pointer arguments must be valid pointers.
1084     unsafe extern "C" fn exit_callback(ptr: *mut bindings::cpufreq_policy) {
1085         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1086         // lifetime of `policy`.
1087         let policy = unsafe { Policy::from_raw_mut(ptr) };
1088 
1089         let data = policy.clear_data();
1090         let _ = T::exit(policy, data);
1091     }
1092 
1093     /// Driver's `online` 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 online_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1100         from_result(|| {
1101             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1102             // lifetime of `policy`.
1103             let policy = unsafe { Policy::from_raw_mut(ptr) };
1104             T::online(policy).map(|()| 0)
1105         })
1106     }
1107 
1108     /// Driver's `offline` 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 offline_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::offline(policy).map(|()| 0)
1120         })
1121     }
1122 
1123     /// Driver's `suspend` 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 suspend_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::suspend(policy).map(|()| 0)
1135         })
1136     }
1137 
1138     /// Driver's `resume` 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 resume_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::resume(policy).map(|()| 0)
1150         })
1151     }
1152 
1153     /// Driver's `ready` 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 ready_callback(ptr: *mut bindings::cpufreq_policy) {
1160         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1161         // lifetime of `policy`.
1162         let policy = unsafe { Policy::from_raw_mut(ptr) };
1163         T::ready(policy);
1164     }
1165 
1166     /// Driver's `verify` callback.
1167     ///
1168     /// # Safety
1169     ///
1170     /// - This function may only be called from the cpufreq C infrastructure.
1171     /// - The pointer arguments must be valid pointers.
1172     unsafe extern "C" fn verify_callback(ptr: *mut bindings::cpufreq_policy_data) -> c_int {
1173         from_result(|| {
1174             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1175             // lifetime of `policy`.
1176             let data = unsafe { PolicyData::from_raw_mut(ptr) };
1177             T::verify(data).map(|()| 0)
1178         })
1179     }
1180 
1181     /// Driver's `setpolicy` 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 setpolicy_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1188         from_result(|| {
1189             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1190             // lifetime of `policy`.
1191             let policy = unsafe { Policy::from_raw_mut(ptr) };
1192             T::setpolicy(policy).map(|()| 0)
1193         })
1194     }
1195 
1196     /// Driver's `target` 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 target_callback(
1203         ptr: *mut bindings::cpufreq_policy,
1204         target_freq: c_uint,
1205         relation: c_uint,
1206     ) -> c_int {
1207         from_result(|| {
1208             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1209             // lifetime of `policy`.
1210             let policy = unsafe { Policy::from_raw_mut(ptr) };
1211             T::target(policy, target_freq, Relation::new(relation)?).map(|()| 0)
1212         })
1213     }
1214 
1215     /// Driver's `target_index` callback.
1216     ///
1217     /// # Safety
1218     ///
1219     /// - This function may only be called from the cpufreq C infrastructure.
1220     /// - The pointer arguments must be valid pointers.
1221     unsafe extern "C" fn target_index_callback(
1222         ptr: *mut bindings::cpufreq_policy,
1223         index: c_uint,
1224     ) -> c_int {
1225         from_result(|| {
1226             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1227             // lifetime of `policy`.
1228             let policy = unsafe { Policy::from_raw_mut(ptr) };
1229 
1230             // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1231             // frequency table.
1232             let index = unsafe { TableIndex::new(index as usize) };
1233 
1234             T::target_index(policy, index).map(|()| 0)
1235         })
1236     }
1237 
1238     /// Driver's `fast_switch` callback.
1239     ///
1240     /// # Safety
1241     ///
1242     /// - This function may only be called from the cpufreq C infrastructure.
1243     /// - The pointer arguments must be valid pointers.
1244     unsafe extern "C" fn fast_switch_callback(
1245         ptr: *mut bindings::cpufreq_policy,
1246         target_freq: c_uint,
1247     ) -> c_uint {
1248         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1249         // lifetime of `policy`.
1250         let policy = unsafe { Policy::from_raw_mut(ptr) };
1251         T::fast_switch(policy, target_freq)
1252     }
1253 
1254     /// Driver's `adjust_perf` callback.
1255     ///
1256     /// # Safety
1257     ///
1258     /// - This function may only be called from the cpufreq C infrastructure.
1259     unsafe extern "C" fn adjust_perf_callback(
1260         cpu: c_uint,
1261         min_perf: c_ulong,
1262         target_perf: c_ulong,
1263         capacity: c_ulong,
1264     ) {
1265         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1266         let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
1267 
1268         if let Ok(mut policy) = PolicyCpu::from_cpu(cpu_id) {
1269             T::adjust_perf(&mut policy, min_perf, target_perf, capacity);
1270         }
1271     }
1272 
1273     /// Driver's `get_intermediate` callback.
1274     ///
1275     /// # Safety
1276     ///
1277     /// - This function may only be called from the cpufreq C infrastructure.
1278     /// - The pointer arguments must be valid pointers.
1279     unsafe extern "C" fn get_intermediate_callback(
1280         ptr: *mut bindings::cpufreq_policy,
1281         index: c_uint,
1282     ) -> c_uint {
1283         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1284         // lifetime of `policy`.
1285         let policy = unsafe { Policy::from_raw_mut(ptr) };
1286 
1287         // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1288         // frequency table.
1289         let index = unsafe { TableIndex::new(index as usize) };
1290 
1291         T::get_intermediate(policy, index)
1292     }
1293 
1294     /// Driver's `target_intermediate` callback.
1295     ///
1296     /// # Safety
1297     ///
1298     /// - This function may only be called from the cpufreq C infrastructure.
1299     /// - The pointer arguments must be valid pointers.
1300     unsafe extern "C" fn target_intermediate_callback(
1301         ptr: *mut bindings::cpufreq_policy,
1302         index: c_uint,
1303     ) -> c_int {
1304         from_result(|| {
1305             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1306             // lifetime of `policy`.
1307             let policy = unsafe { Policy::from_raw_mut(ptr) };
1308 
1309             // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1310             // frequency table.
1311             let index = unsafe { TableIndex::new(index as usize) };
1312 
1313             T::target_intermediate(policy, index).map(|()| 0)
1314         })
1315     }
1316 
1317     /// Driver's `get` callback.
1318     ///
1319     /// # Safety
1320     ///
1321     /// - This function may only be called from the cpufreq C infrastructure.
1322     unsafe extern "C" fn get_callback(cpu: c_uint) -> c_uint {
1323         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1324         let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
1325 
1326         PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
1327     }
1328 
1329     /// Driver's `update_limit` callback.
1330     ///
1331     /// # Safety
1332     ///
1333     /// - This function may only be called from the cpufreq C infrastructure.
1334     /// - The pointer arguments must be valid pointers.
1335     unsafe extern "C" fn update_limits_callback(ptr: *mut bindings::cpufreq_policy) {
1336         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1337         // lifetime of `policy`.
1338         let policy = unsafe { Policy::from_raw_mut(ptr) };
1339         T::update_limits(policy);
1340     }
1341 
1342     /// Driver's `bios_limit` callback.
1343     ///
1344     /// # Safety
1345     ///
1346     /// - This function may only be called from the cpufreq C infrastructure.
1347     /// - The pointer arguments must be valid pointers.
1348     unsafe extern "C" fn bios_limit_callback(cpu: c_int, limit: *mut c_uint) -> c_int {
1349         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1350         let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) };
1351 
1352         from_result(|| {
1353             let mut policy = PolicyCpu::from_cpu(cpu_id)?;
1354 
1355             // SAFETY: `limit` is guaranteed by the C code to be valid.
1356             T::bios_limit(&mut policy, &mut (unsafe { *limit })).map(|()| 0)
1357         })
1358     }
1359 
1360     /// Driver's `set_boost` callback.
1361     ///
1362     /// # Safety
1363     ///
1364     /// - This function may only be called from the cpufreq C infrastructure.
1365     /// - The pointer arguments must be valid pointers.
1366     unsafe extern "C" fn set_boost_callback(
1367         ptr: *mut bindings::cpufreq_policy,
1368         state: c_int,
1369     ) -> c_int {
1370         from_result(|| {
1371             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1372             // lifetime of `policy`.
1373             let policy = unsafe { Policy::from_raw_mut(ptr) };
1374             T::set_boost(policy, state).map(|()| 0)
1375         })
1376     }
1377 
1378     /// Driver's `register_em` 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 register_em_callback(ptr: *mut bindings::cpufreq_policy) {
1385         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1386         // lifetime of `policy`.
1387         let policy = unsafe { Policy::from_raw_mut(ptr) };
1388         T::register_em(policy);
1389     }
1390 }
1391 
1392 impl<T: Driver> Drop for Registration<T> {
1393     /// Unregisters with the cpufreq core.
1394     fn drop(&mut self) {
1395         // SAFETY: `self.0` is guaranteed to be valid for the lifetime of `Registration`.
1396         unsafe { bindings::cpufreq_unregister_driver(self.0.get_mut()) };
1397     }
1398 }
1399