xref: /linux/rust/kernel/cpufreq.rs (revision 182d95571ffa278f7c68a80d76de88a5333fb69f)
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 ETERNAL_LATENCY_NS: u32 = bindings::CPUFREQ_ETERNAL as u32;
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::{ETERNAL_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(ETERNAL_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::as_mut_ref(&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 ///     c_str,
844 ///     device::{Core, Device},
845 ///     macros::vtable,
846 ///     of, platform,
847 ///     sync::Arc,
848 /// };
849 /// struct SampleDevice;
850 ///
851 /// #[derive(Default)]
852 /// struct SampleDriver;
853 ///
854 /// #[vtable]
855 /// impl cpufreq::Driver for SampleDriver {
856 ///     const NAME: &'static CStr = c_str!("cpufreq-sample");
857 ///     const FLAGS: u16 = cpufreq::flags::NEED_INITIAL_FREQ_CHECK | cpufreq::flags::IS_COOLING_DEV;
858 ///     const BOOST_ENABLED: bool = true;
859 ///
860 ///     type PData = Arc<SampleDevice>;
861 ///
862 ///     fn init(policy: &mut cpufreq::Policy) -> Result<Self::PData> {
863 ///         // Initialize here
864 ///         Ok(Arc::new(SampleDevice, GFP_KERNEL)?)
865 ///     }
866 ///
867 ///     fn exit(_policy: &mut cpufreq::Policy, _data: Option<Self::PData>) -> Result {
868 ///         Ok(())
869 ///     }
870 ///
871 ///     fn suspend(policy: &mut cpufreq::Policy) -> Result {
872 ///         policy.generic_suspend()
873 ///     }
874 ///
875 ///     fn verify(data: &mut cpufreq::PolicyData) -> Result {
876 ///         data.generic_verify()
877 ///     }
878 ///
879 ///     fn target_index(policy: &mut cpufreq::Policy, index: cpufreq::TableIndex) -> Result {
880 ///         // Update CPU frequency
881 ///         Ok(())
882 ///     }
883 ///
884 ///     fn get(policy: &mut cpufreq::Policy) -> Result<u32> {
885 ///         policy.generic_get()
886 ///     }
887 /// }
888 ///
889 /// impl platform::Driver for SampleDriver {
890 ///     type IdInfo = ();
891 ///     const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
892 ///
893 ///     fn probe(
894 ///         pdev: &platform::Device<Core>,
895 ///         _id_info: Option<&Self::IdInfo>,
896 ///     ) -> Result<Pin<KBox<Self>>> {
897 ///         cpufreq::Registration::<SampleDriver>::new_foreign_owned(pdev.as_ref())?;
898 ///         Ok(KBox::new(Self {}, GFP_KERNEL)?.into())
899 ///     }
900 /// }
901 /// ```
902 #[repr(transparent)]
903 pub struct Registration<T: Driver>(KBox<UnsafeCell<bindings::cpufreq_driver>>, PhantomData<T>);
904 
905 /// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between threads
906 /// or CPUs, so it is safe to share it.
907 unsafe impl<T: Driver> Sync for Registration<T> {}
908 
909 #[allow(clippy::non_send_fields_in_send_ty)]
910 /// SAFETY: Registration with and unregistration from the cpufreq subsystem can happen from any
911 /// thread.
912 unsafe impl<T: Driver> Send for Registration<T> {}
913 
914 impl<T: Driver> Registration<T> {
915     const VTABLE: bindings::cpufreq_driver = bindings::cpufreq_driver {
916         name: Self::copy_name(T::NAME),
917         boost_enabled: T::BOOST_ENABLED,
918         flags: T::FLAGS,
919 
920         // Initialize mandatory callbacks.
921         init: Some(Self::init_callback),
922         verify: Some(Self::verify_callback),
923 
924         // Initialize optional callbacks based on the traits of `T`.
925         setpolicy: if T::HAS_SETPOLICY {
926             Some(Self::setpolicy_callback)
927         } else {
928             None
929         },
930         target: if T::HAS_TARGET {
931             Some(Self::target_callback)
932         } else {
933             None
934         },
935         target_index: if T::HAS_TARGET_INDEX {
936             Some(Self::target_index_callback)
937         } else {
938             None
939         },
940         fast_switch: if T::HAS_FAST_SWITCH {
941             Some(Self::fast_switch_callback)
942         } else {
943             None
944         },
945         adjust_perf: if T::HAS_ADJUST_PERF {
946             Some(Self::adjust_perf_callback)
947         } else {
948             None
949         },
950         get_intermediate: if T::HAS_GET_INTERMEDIATE {
951             Some(Self::get_intermediate_callback)
952         } else {
953             None
954         },
955         target_intermediate: if T::HAS_TARGET_INTERMEDIATE {
956             Some(Self::target_intermediate_callback)
957         } else {
958             None
959         },
960         get: if T::HAS_GET {
961             Some(Self::get_callback)
962         } else {
963             None
964         },
965         update_limits: if T::HAS_UPDATE_LIMITS {
966             Some(Self::update_limits_callback)
967         } else {
968             None
969         },
970         bios_limit: if T::HAS_BIOS_LIMIT {
971             Some(Self::bios_limit_callback)
972         } else {
973             None
974         },
975         online: if T::HAS_ONLINE {
976             Some(Self::online_callback)
977         } else {
978             None
979         },
980         offline: if T::HAS_OFFLINE {
981             Some(Self::offline_callback)
982         } else {
983             None
984         },
985         exit: if T::HAS_EXIT {
986             Some(Self::exit_callback)
987         } else {
988             None
989         },
990         suspend: if T::HAS_SUSPEND {
991             Some(Self::suspend_callback)
992         } else {
993             None
994         },
995         resume: if T::HAS_RESUME {
996             Some(Self::resume_callback)
997         } else {
998             None
999         },
1000         ready: if T::HAS_READY {
1001             Some(Self::ready_callback)
1002         } else {
1003             None
1004         },
1005         set_boost: if T::HAS_SET_BOOST {
1006             Some(Self::set_boost_callback)
1007         } else {
1008             None
1009         },
1010         register_em: if T::HAS_REGISTER_EM {
1011             Some(Self::register_em_callback)
1012         } else {
1013             None
1014         },
1015         ..pin_init::zeroed()
1016     };
1017 
1018     const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] {
1019         let src = name.to_bytes_with_nul();
1020         let mut dst = [0; CPUFREQ_NAME_LEN];
1021 
1022         build_assert!(src.len() <= CPUFREQ_NAME_LEN);
1023 
1024         let mut i = 0;
1025         while i < src.len() {
1026             dst[i] = src[i];
1027             i += 1;
1028         }
1029 
1030         dst
1031     }
1032 
1033     /// Registers a CPU frequency driver with the cpufreq core.
1034     pub fn new() -> Result<Self> {
1035         // We can't use `&Self::VTABLE` directly because the cpufreq core modifies some fields in
1036         // the C `struct cpufreq_driver`, which requires a mutable reference.
1037         let mut drv = KBox::new(UnsafeCell::new(Self::VTABLE), GFP_KERNEL)?;
1038 
1039         // SAFETY: `drv` is guaranteed to be valid for the lifetime of `Registration`.
1040         to_result(unsafe { bindings::cpufreq_register_driver(drv.get_mut()) })?;
1041 
1042         Ok(Self(drv, PhantomData))
1043     }
1044 
1045     /// Same as [`Registration::new`], but does not return a [`Registration`] instance.
1046     ///
1047     /// Instead the [`Registration`] is owned by [`devres::register`] and will be dropped, once the
1048     /// device is detached.
1049     pub fn new_foreign_owned(dev: &Device<Bound>) -> Result
1050     where
1051         T: 'static,
1052     {
1053         devres::register(dev, Self::new()?, GFP_KERNEL)
1054     }
1055 }
1056 
1057 /// CPU frequency driver callbacks.
1058 impl<T: Driver> Registration<T> {
1059     /// Driver's `init` callback.
1060     ///
1061     /// # Safety
1062     ///
1063     /// - This function may only be called from the cpufreq C infrastructure.
1064     /// - The pointer arguments must be valid pointers.
1065     unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1066         from_result(|| {
1067             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1068             // lifetime of `policy`.
1069             let policy = unsafe { Policy::from_raw_mut(ptr) };
1070 
1071             let data = T::init(policy)?;
1072             policy.set_data(data)?;
1073             Ok(0)
1074         })
1075     }
1076 
1077     /// Driver's `exit` callback.
1078     ///
1079     /// # Safety
1080     ///
1081     /// - This function may only be called from the cpufreq C infrastructure.
1082     /// - The pointer arguments must be valid pointers.
1083     unsafe extern "C" fn exit_callback(ptr: *mut bindings::cpufreq_policy) {
1084         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1085         // lifetime of `policy`.
1086         let policy = unsafe { Policy::from_raw_mut(ptr) };
1087 
1088         let data = policy.clear_data();
1089         let _ = T::exit(policy, data);
1090     }
1091 
1092     /// Driver's `online` callback.
1093     ///
1094     /// # Safety
1095     ///
1096     /// - This function may only be called from the cpufreq C infrastructure.
1097     /// - The pointer arguments must be valid pointers.
1098     unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1099         from_result(|| {
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             T::online(policy).map(|()| 0)
1104         })
1105     }
1106 
1107     /// Driver's `offline` callback.
1108     ///
1109     /// # Safety
1110     ///
1111     /// - This function may only be called from the cpufreq C infrastructure.
1112     /// - The pointer arguments must be valid pointers.
1113     unsafe extern "C" fn offline_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1114         from_result(|| {
1115             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1116             // lifetime of `policy`.
1117             let policy = unsafe { Policy::from_raw_mut(ptr) };
1118             T::offline(policy).map(|()| 0)
1119         })
1120     }
1121 
1122     /// Driver's `suspend` callback.
1123     ///
1124     /// # Safety
1125     ///
1126     /// - This function may only be called from the cpufreq C infrastructure.
1127     /// - The pointer arguments must be valid pointers.
1128     unsafe extern "C" fn suspend_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1129         from_result(|| {
1130             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1131             // lifetime of `policy`.
1132             let policy = unsafe { Policy::from_raw_mut(ptr) };
1133             T::suspend(policy).map(|()| 0)
1134         })
1135     }
1136 
1137     /// Driver's `resume` callback.
1138     ///
1139     /// # Safety
1140     ///
1141     /// - This function may only be called from the cpufreq C infrastructure.
1142     /// - The pointer arguments must be valid pointers.
1143     unsafe extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1144         from_result(|| {
1145             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1146             // lifetime of `policy`.
1147             let policy = unsafe { Policy::from_raw_mut(ptr) };
1148             T::resume(policy).map(|()| 0)
1149         })
1150     }
1151 
1152     /// Driver's `ready` callback.
1153     ///
1154     /// # Safety
1155     ///
1156     /// - This function may only be called from the cpufreq C infrastructure.
1157     /// - The pointer arguments must be valid pointers.
1158     unsafe extern "C" fn ready_callback(ptr: *mut bindings::cpufreq_policy) {
1159         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1160         // lifetime of `policy`.
1161         let policy = unsafe { Policy::from_raw_mut(ptr) };
1162         T::ready(policy);
1163     }
1164 
1165     /// Driver's `verify` callback.
1166     ///
1167     /// # Safety
1168     ///
1169     /// - This function may only be called from the cpufreq C infrastructure.
1170     /// - The pointer arguments must be valid pointers.
1171     unsafe extern "C" fn verify_callback(ptr: *mut bindings::cpufreq_policy_data) -> c_int {
1172         from_result(|| {
1173             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1174             // lifetime of `policy`.
1175             let data = unsafe { PolicyData::from_raw_mut(ptr) };
1176             T::verify(data).map(|()| 0)
1177         })
1178     }
1179 
1180     /// Driver's `setpolicy` callback.
1181     ///
1182     /// # Safety
1183     ///
1184     /// - This function may only be called from the cpufreq C infrastructure.
1185     /// - The pointer arguments must be valid pointers.
1186     unsafe extern "C" fn setpolicy_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1187         from_result(|| {
1188             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1189             // lifetime of `policy`.
1190             let policy = unsafe { Policy::from_raw_mut(ptr) };
1191             T::setpolicy(policy).map(|()| 0)
1192         })
1193     }
1194 
1195     /// Driver's `target` callback.
1196     ///
1197     /// # Safety
1198     ///
1199     /// - This function may only be called from the cpufreq C infrastructure.
1200     /// - The pointer arguments must be valid pointers.
1201     unsafe extern "C" fn target_callback(
1202         ptr: *mut bindings::cpufreq_policy,
1203         target_freq: c_uint,
1204         relation: c_uint,
1205     ) -> c_int {
1206         from_result(|| {
1207             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1208             // lifetime of `policy`.
1209             let policy = unsafe { Policy::from_raw_mut(ptr) };
1210             T::target(policy, target_freq, Relation::new(relation)?).map(|()| 0)
1211         })
1212     }
1213 
1214     /// Driver's `target_index` callback.
1215     ///
1216     /// # Safety
1217     ///
1218     /// - This function may only be called from the cpufreq C infrastructure.
1219     /// - The pointer arguments must be valid pointers.
1220     unsafe extern "C" fn target_index_callback(
1221         ptr: *mut bindings::cpufreq_policy,
1222         index: c_uint,
1223     ) -> c_int {
1224         from_result(|| {
1225             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1226             // lifetime of `policy`.
1227             let policy = unsafe { Policy::from_raw_mut(ptr) };
1228 
1229             // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1230             // frequency table.
1231             let index = unsafe { TableIndex::new(index as usize) };
1232 
1233             T::target_index(policy, index).map(|()| 0)
1234         })
1235     }
1236 
1237     /// Driver's `fast_switch` callback.
1238     ///
1239     /// # Safety
1240     ///
1241     /// - This function may only be called from the cpufreq C infrastructure.
1242     /// - The pointer arguments must be valid pointers.
1243     unsafe extern "C" fn fast_switch_callback(
1244         ptr: *mut bindings::cpufreq_policy,
1245         target_freq: c_uint,
1246     ) -> c_uint {
1247         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1248         // lifetime of `policy`.
1249         let policy = unsafe { Policy::from_raw_mut(ptr) };
1250         T::fast_switch(policy, target_freq)
1251     }
1252 
1253     /// Driver's `adjust_perf` callback.
1254     ///
1255     /// # Safety
1256     ///
1257     /// - This function may only be called from the cpufreq C infrastructure.
1258     unsafe extern "C" fn adjust_perf_callback(
1259         cpu: c_uint,
1260         min_perf: c_ulong,
1261         target_perf: c_ulong,
1262         capacity: c_ulong,
1263     ) {
1264         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1265         let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
1266 
1267         if let Ok(mut policy) = PolicyCpu::from_cpu(cpu_id) {
1268             T::adjust_perf(&mut policy, min_perf, target_perf, capacity);
1269         }
1270     }
1271 
1272     /// Driver's `get_intermediate` callback.
1273     ///
1274     /// # Safety
1275     ///
1276     /// - This function may only be called from the cpufreq C infrastructure.
1277     /// - The pointer arguments must be valid pointers.
1278     unsafe extern "C" fn get_intermediate_callback(
1279         ptr: *mut bindings::cpufreq_policy,
1280         index: c_uint,
1281     ) -> c_uint {
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 
1286         // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1287         // frequency table.
1288         let index = unsafe { TableIndex::new(index as usize) };
1289 
1290         T::get_intermediate(policy, index)
1291     }
1292 
1293     /// Driver's `target_intermediate` callback.
1294     ///
1295     /// # Safety
1296     ///
1297     /// - This function may only be called from the cpufreq C infrastructure.
1298     /// - The pointer arguments must be valid pointers.
1299     unsafe extern "C" fn target_intermediate_callback(
1300         ptr: *mut bindings::cpufreq_policy,
1301         index: c_uint,
1302     ) -> c_int {
1303         from_result(|| {
1304             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1305             // lifetime of `policy`.
1306             let policy = unsafe { Policy::from_raw_mut(ptr) };
1307 
1308             // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1309             // frequency table.
1310             let index = unsafe { TableIndex::new(index as usize) };
1311 
1312             T::target_intermediate(policy, index).map(|()| 0)
1313         })
1314     }
1315 
1316     /// Driver's `get` callback.
1317     ///
1318     /// # Safety
1319     ///
1320     /// - This function may only be called from the cpufreq C infrastructure.
1321     unsafe extern "C" fn get_callback(cpu: c_uint) -> c_uint {
1322         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1323         let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
1324 
1325         PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
1326     }
1327 
1328     /// Driver's `update_limit` callback.
1329     ///
1330     /// # Safety
1331     ///
1332     /// - This function may only be called from the cpufreq C infrastructure.
1333     /// - The pointer arguments must be valid pointers.
1334     unsafe extern "C" fn update_limits_callback(ptr: *mut bindings::cpufreq_policy) {
1335         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1336         // lifetime of `policy`.
1337         let policy = unsafe { Policy::from_raw_mut(ptr) };
1338         T::update_limits(policy);
1339     }
1340 
1341     /// Driver's `bios_limit` callback.
1342     ///
1343     /// # Safety
1344     ///
1345     /// - This function may only be called from the cpufreq C infrastructure.
1346     /// - The pointer arguments must be valid pointers.
1347     unsafe extern "C" fn bios_limit_callback(cpu: c_int, limit: *mut c_uint) -> c_int {
1348         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1349         let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) };
1350 
1351         from_result(|| {
1352             let mut policy = PolicyCpu::from_cpu(cpu_id)?;
1353 
1354             // SAFETY: `limit` is guaranteed by the C code to be valid.
1355             T::bios_limit(&mut policy, &mut (unsafe { *limit })).map(|()| 0)
1356         })
1357     }
1358 
1359     /// Driver's `set_boost` callback.
1360     ///
1361     /// # Safety
1362     ///
1363     /// - This function may only be called from the cpufreq C infrastructure.
1364     /// - The pointer arguments must be valid pointers.
1365     unsafe extern "C" fn set_boost_callback(
1366         ptr: *mut bindings::cpufreq_policy,
1367         state: c_int,
1368     ) -> c_int {
1369         from_result(|| {
1370             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1371             // lifetime of `policy`.
1372             let policy = unsafe { Policy::from_raw_mut(ptr) };
1373             T::set_boost(policy, state).map(|()| 0)
1374         })
1375     }
1376 
1377     /// Driver's `register_em` callback.
1378     ///
1379     /// # Safety
1380     ///
1381     /// - This function may only be called from the cpufreq C infrastructure.
1382     /// - The pointer arguments must be valid pointers.
1383     unsafe extern "C" fn register_em_callback(ptr: *mut bindings::cpufreq_policy) {
1384         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1385         // lifetime of `policy`.
1386         let policy = unsafe { Policy::from_raw_mut(ptr) };
1387         T::register_em(policy);
1388     }
1389 }
1390 
1391 impl<T: Driver> Drop for Registration<T> {
1392     /// Unregisters with the cpufreq core.
1393     fn drop(&mut self) {
1394         // SAFETY: `self.0` is guaranteed to be valid for the lifetime of `Registration`.
1395         unsafe { bindings::cpufreq_unregister_driver(self.0.get_mut()) };
1396     }
1397 }
1398