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