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