xref: /linux/rust/kernel/cpufreq.rs (revision 487f9b3dc6e507a982f1b984aa6bfbd9dc4b0567)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! CPU frequency scaling.
4 //!
5 //! This module provides rust abstractions for interacting with the cpufreq subsystem.
6 //!
7 //! C header: [`include/linux/cpufreq.h`](srctree/include/linux/cpufreq.h)
8 //!
9 //! Reference: <https://docs.kernel.org/admin-guide/pm/cpufreq.html>
10 
11 use crate::{
12     clk::Hertz,
13     cpu::CpuId,
14     cpumask,
15     device::{Bound, Device},
16     devres,
17     error::{code::*, from_err_ptr, from_result, to_result, Result, VTABLE_DEFAULT_ERROR},
18     ffi::{c_char, c_ulong},
19     prelude::*,
20     types::ForeignOwnable,
21     types::Opaque,
22 };
23 
24 #[cfg(CONFIG_COMMON_CLK)]
25 use crate::clk::Clk;
26 
27 use core::{
28     cell::UnsafeCell,
29     marker::PhantomData,
30     ops::{Deref, DerefMut},
31     pin::Pin,
32     ptr,
33 };
34 
35 use macros::vtable;
36 
37 /// Maximum length of CPU frequency driver's name.
38 const CPUFREQ_NAME_LEN: usize = bindings::CPUFREQ_NAME_LEN as usize;
39 
40 /// Default transition latency value in nanoseconds.
41 pub const DEFAULT_TRANSITION_LATENCY_NS: u32 = bindings::CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;
42 
43 /// CPU frequency driver flags.
44 pub mod flags {
45     /// Driver needs to update internal limits even if frequency remains unchanged.
46     pub const NEED_UPDATE_LIMITS: u16 = 1 << 0;
47 
48     /// Platform where constants like `loops_per_jiffy` are unaffected by frequency changes.
49     pub const CONST_LOOPS: u16 = 1 << 1;
50 
51     /// Register driver as a thermal cooling device automatically.
52     pub const IS_COOLING_DEV: u16 = 1 << 2;
53 
54     /// Supports multiple clock domains with per-policy governors in `cpu/cpuN/cpufreq/`.
55     pub const HAVE_GOVERNOR_PER_POLICY: u16 = 1 << 3;
56 
57     /// Allows post-change notifications outside of the `target()` routine.
58     pub const ASYNC_NOTIFICATION: u16 = 1 << 4;
59 
60     /// Ensure CPU starts at a valid frequency from the driver's freq-table.
61     pub const NEED_INITIAL_FREQ_CHECK: u16 = 1 << 5;
62 
63     /// Disallow governors with `dynamic_switching` capability.
64     pub const NO_AUTO_DYNAMIC_SWITCHING: u16 = 1 << 6;
65 }
66 
67 /// Relations from the C code.
68 const CPUFREQ_RELATION_L: u32 = 0;
69 const CPUFREQ_RELATION_H: u32 = 1;
70 const CPUFREQ_RELATION_C: u32 = 2;
71 
72 /// Can be used with any of the above values.
73 const CPUFREQ_RELATION_E: u32 = 1 << 2;
74 
75 /// CPU frequency selection relations.
76 ///
77 /// CPU frequency selection relations, each optionally marked as "efficient".
78 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
79 pub enum Relation {
80     /// Select the lowest frequency at or above target.
81     Low(bool),
82     /// Select the highest frequency below or at target.
83     High(bool),
84     /// Select the closest frequency to the target.
85     Close(bool),
86 }
87 
88 impl Relation {
89     // Construct from a C-compatible `u32` value.
90     fn new(val: u32) -> Result<Self> {
91         let efficient = val & CPUFREQ_RELATION_E != 0;
92 
93         Ok(match val & !CPUFREQ_RELATION_E {
94             CPUFREQ_RELATION_L => Self::Low(efficient),
95             CPUFREQ_RELATION_H => Self::High(efficient),
96             CPUFREQ_RELATION_C => Self::Close(efficient),
97             _ => return Err(EINVAL),
98         })
99     }
100 }
101 
102 impl From<Relation> for u32 {
103     // Convert to a C-compatible `u32` value.
104     fn from(rel: Relation) -> Self {
105         let (mut val, efficient) = match rel {
106             Relation::Low(e) => (CPUFREQ_RELATION_L, e),
107             Relation::High(e) => (CPUFREQ_RELATION_H, e),
108             Relation::Close(e) => (CPUFREQ_RELATION_C, e),
109         };
110 
111         if efficient {
112             val |= CPUFREQ_RELATION_E;
113         }
114 
115         val
116     }
117 }
118 
119 /// Policy data.
120 ///
121 /// Rust abstraction for the C `struct cpufreq_policy_data`.
122 ///
123 /// # Invariants
124 ///
125 /// A [`PolicyData`] instance always corresponds to a valid C `struct cpufreq_policy_data`.
126 ///
127 /// The callers must ensure that the `struct cpufreq_policy_data` is valid for access and remains
128 /// valid for the lifetime of the returned reference.
129 #[repr(transparent)]
130 pub struct PolicyData(Opaque<bindings::cpufreq_policy_data>);
131 
132 impl PolicyData {
133     /// Creates a mutable reference to an existing `struct cpufreq_policy_data` pointer.
134     ///
135     /// # Safety
136     ///
137     /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime
138     /// of the returned reference.
139     #[inline]
140     pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy_data) -> &'a mut Self {
141         // SAFETY: Guaranteed by the safety requirements of the function.
142         //
143         // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the
144         // lifetime of the returned reference.
145         unsafe { &mut *ptr.cast() }
146     }
147 
148     /// Returns a raw pointer to the underlying C `cpufreq_policy_data`.
149     #[inline]
150     pub fn as_raw(&self) -> *mut bindings::cpufreq_policy_data {
151         let this: *const Self = self;
152         this.cast_mut().cast()
153     }
154 
155     /// Wrapper for `cpufreq_generic_frequency_table_verify`.
156     #[inline]
157     pub fn generic_verify(&self) -> Result {
158         // SAFETY: By the type invariant, the pointer stored in `self` is valid.
159         to_result(unsafe { bindings::cpufreq_generic_frequency_table_verify(self.as_raw()) })
160     }
161 }
162 
163 /// The frequency table index.
164 ///
165 /// Represents index with a frequency table.
166 ///
167 /// # Invariants
168 ///
169 /// The index must correspond to a valid entry in the [`Table`] it is used for.
170 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
171 pub struct TableIndex(usize);
172 
173 impl TableIndex {
174     /// Creates an instance of [`TableIndex`].
175     ///
176     /// # Safety
177     ///
178     /// The caller must ensure that `index` correspond to a valid entry in the [`Table`] it is used
179     /// for.
180     pub unsafe fn new(index: usize) -> Self {
181         // INVARIANT: The caller ensures that `index` correspond to a valid entry in the [`Table`].
182         Self(index)
183     }
184 }
185 
186 impl From<TableIndex> for usize {
187     #[inline]
188     fn from(index: TableIndex) -> Self {
189         index.0
190     }
191 }
192 
193 /// CPU frequency table.
194 ///
195 /// Rust abstraction for the C `struct cpufreq_frequency_table`.
196 ///
197 /// # Invariants
198 ///
199 /// A [`Table`] instance always corresponds to a valid C `struct cpufreq_frequency_table`.
200 ///
201 /// The callers must ensure that the `struct cpufreq_frequency_table` is valid for access and
202 /// remains valid for the lifetime of the returned reference.
203 ///
204 /// # Examples
205 ///
206 /// The following example demonstrates how to read a frequency value from [`Table`].
207 ///
208 /// ```
209 /// use kernel::cpufreq::{Policy, TableIndex};
210 ///
211 /// fn show_freq(policy: &Policy) -> Result {
212 ///     let table = policy.freq_table()?;
213 ///
214 ///     // SAFETY: Index is a valid entry in the table.
215 ///     let index = unsafe { TableIndex::new(0) };
216 ///
217 ///     pr_info!("The frequency at index 0 is: {:?}\n", table.freq(index)?);
218 ///     pr_info!("The flags at index 0 is: {}\n", table.flags(index));
219 ///     pr_info!("The data at index 0 is: {}\n", table.data(index));
220 ///     Ok(())
221 /// }
222 /// ```
223 #[repr(transparent)]
224 pub struct Table(Opaque<bindings::cpufreq_frequency_table>);
225 
226 impl Table {
227     /// Creates a reference to an existing C `struct cpufreq_frequency_table` pointer.
228     ///
229     /// # Safety
230     ///
231     /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime
232     /// of the returned reference.
233     #[inline]
234     pub unsafe fn from_raw<'a>(ptr: *const bindings::cpufreq_frequency_table) -> &'a Self {
235         // SAFETY: Guaranteed by the safety requirements of the function.
236         //
237         // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the
238         // lifetime of the returned reference.
239         unsafe { &*ptr.cast() }
240     }
241 
242     /// Returns the raw mutable pointer to the C `struct cpufreq_frequency_table`.
243     #[inline]
244     pub fn as_raw(&self) -> *mut bindings::cpufreq_frequency_table {
245         let this: *const Self = self;
246         this.cast_mut().cast()
247     }
248 
249     /// Returns frequency at `index` in the [`Table`].
250     #[inline]
251     pub fn freq(&self, index: TableIndex) -> Result<Hertz> {
252         // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
253         // guaranteed to be valid by its safety requirements.
254         Ok(Hertz::from_khz(unsafe {
255             (*self.as_raw().add(index.into())).frequency.try_into()?
256         }))
257     }
258 
259     /// Returns flags at `index` in the [`Table`].
260     #[inline]
261     pub fn flags(&self, index: TableIndex) -> u32 {
262         // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
263         // guaranteed to be valid by its safety requirements.
264         unsafe { (*self.as_raw().add(index.into())).flags }
265     }
266 
267     /// Returns data at `index` in the [`Table`].
268     #[inline]
269     pub fn data(&self, index: TableIndex) -> u32 {
270         // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
271         // guaranteed to be valid by its safety requirements.
272         unsafe { (*self.as_raw().add(index.into())).driver_data }
273     }
274 }
275 
276 /// CPU frequency table owned and pinned in memory, created from a [`TableBuilder`].
277 pub struct TableBox {
278     entries: Pin<KVec<bindings::cpufreq_frequency_table>>,
279 }
280 
281 impl TableBox {
282     /// Constructs a new [`TableBox`] from a [`KVec`] of entries.
283     ///
284     /// # Errors
285     ///
286     /// Returns `EINVAL` if the entries list is empty.
287     #[inline]
288     fn new(entries: KVec<bindings::cpufreq_frequency_table>) -> Result<Self> {
289         if entries.is_empty() {
290             return Err(EINVAL);
291         }
292 
293         Ok(Self {
294             // Pin the entries to memory, since we are passing its pointer to the C code.
295             entries: Pin::new(entries),
296         })
297     }
298 
299     /// Returns a raw pointer to the underlying C `cpufreq_frequency_table`.
300     #[inline]
301     fn as_raw(&self) -> *const bindings::cpufreq_frequency_table {
302         // The pointer is valid until the table gets dropped.
303         self.entries.as_ptr()
304     }
305 }
306 
307 impl Deref for TableBox {
308     type Target = Table;
309 
310     fn deref(&self) -> &Self::Target {
311         // SAFETY: The caller owns TableBox, it is safe to deref.
312         unsafe { Self::Target::from_raw(self.as_raw()) }
313     }
314 }
315 
316 /// CPU frequency table builder.
317 ///
318 /// This is used by the CPU frequency drivers to build a frequency table dynamically.
319 ///
320 /// # Examples
321 ///
322 /// The following example demonstrates how to create a CPU frequency table.
323 ///
324 /// ```
325 /// use kernel::cpufreq::{TableBuilder, TableIndex};
326 /// use kernel::clk::Hertz;
327 ///
328 /// let mut builder = TableBuilder::new();
329 ///
330 /// // Adds few entries to the table.
331 /// builder.add(Hertz::from_mhz(700), 0, 1).unwrap();
332 /// builder.add(Hertz::from_mhz(800), 2, 3).unwrap();
333 /// builder.add(Hertz::from_mhz(900), 4, 5).unwrap();
334 /// builder.add(Hertz::from_ghz(1), 6, 7).unwrap();
335 ///
336 /// let table = builder.to_table().unwrap();
337 ///
338 /// // SAFETY: Index values correspond to valid entries in the table.
339 /// let (index0, index2) = unsafe { (TableIndex::new(0), TableIndex::new(2)) };
340 ///
341 /// assert_eq!(table.freq(index0), Ok(Hertz::from_mhz(700)));
342 /// assert_eq!(table.flags(index0), 0);
343 /// assert_eq!(table.data(index0), 1);
344 ///
345 /// assert_eq!(table.freq(index2), Ok(Hertz::from_mhz(900)));
346 /// assert_eq!(table.flags(index2), 4);
347 /// assert_eq!(table.data(index2), 5);
348 /// ```
349 #[derive(Default)]
350 #[repr(transparent)]
351 pub struct TableBuilder {
352     entries: KVec<bindings::cpufreq_frequency_table>,
353 }
354 
355 impl TableBuilder {
356     /// Creates a new instance of [`TableBuilder`].
357     #[inline]
358     pub fn new() -> Self {
359         Self {
360             entries: KVec::new(),
361         }
362     }
363 
364     /// Adds a new entry to the table.
365     pub fn add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result {
366         // Adds the new entry at the end of the vector.
367         Ok(self.entries.push(
368             bindings::cpufreq_frequency_table {
369                 flags,
370                 driver_data,
371                 frequency: freq.as_khz() as u32,
372             },
373             GFP_KERNEL,
374         )?)
375     }
376 
377     /// Consumes the [`TableBuilder`] and returns [`TableBox`].
378     pub fn to_table(mut self) -> Result<TableBox> {
379         // Add last entry to the table.
380         self.add(Hertz(c_ulong::MAX), 0, 0)?;
381 
382         TableBox::new(self.entries)
383     }
384 }
385 
386 /// CPU frequency policy.
387 ///
388 /// Rust abstraction for the C `struct cpufreq_policy`.
389 ///
390 /// # Invariants
391 ///
392 /// A [`Policy`] instance always corresponds to a valid C `struct cpufreq_policy`.
393 ///
394 /// The callers must ensure that the `struct cpufreq_policy` is valid for access and remains valid
395 /// for the lifetime of the returned reference.
396 ///
397 /// # Examples
398 ///
399 /// The following example demonstrates how to create a CPU frequency table.
400 ///
401 /// ```
402 /// use kernel::cpufreq::{DEFAULT_TRANSITION_LATENCY_NS, Policy};
403 ///
404 /// #[allow(clippy::double_parens, reason = "False positive before 1.92.0")]
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(DEFAULT_TRANSITION_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::from_raw_mut(&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).cast();
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 ///     device::{Core, Device},
845 ///     macros::vtable,
846 ///     of, platform,
847 ///     sync::Arc,
848 /// };
849 /// struct SampleDevice;
850 ///
851 /// #[derive(Default)]
852 /// struct SampleDriver;
853 ///
854 /// #[vtable]
855 /// impl cpufreq::Driver for SampleDriver {
856 ///     const NAME: &'static CStr = c"cpufreq-sample";
857 ///     const FLAGS: u16 = cpufreq::flags::NEED_INITIAL_FREQ_CHECK | cpufreq::flags::IS_COOLING_DEV;
858 ///     const BOOST_ENABLED: bool = true;
859 ///
860 ///     type PData = Arc<SampleDevice>;
861 ///
862 ///     fn init(policy: &mut cpufreq::Policy) -> Result<Self::PData> {
863 ///         // Initialize here
864 ///         Ok(Arc::new(SampleDevice, GFP_KERNEL)?)
865 ///     }
866 ///
867 ///     fn exit(_policy: &mut cpufreq::Policy, _data: Option<Self::PData>) -> Result {
868 ///         Ok(())
869 ///     }
870 ///
871 ///     fn suspend(policy: &mut cpufreq::Policy) -> Result {
872 ///         policy.generic_suspend()
873 ///     }
874 ///
875 ///     fn verify(data: &mut cpufreq::PolicyData) -> Result {
876 ///         data.generic_verify()
877 ///     }
878 ///
879 ///     fn target_index(policy: &mut cpufreq::Policy, index: cpufreq::TableIndex) -> Result {
880 ///         // Update CPU frequency
881 ///         Ok(())
882 ///     }
883 ///
884 ///     fn get(policy: &mut cpufreq::Policy) -> Result<u32> {
885 ///         policy.generic_get()
886 ///     }
887 /// }
888 ///
889 /// impl platform::Driver for SampleDriver {
890 ///     type IdInfo = ();
891 ///     const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
892 ///
893 ///     fn probe(
894 ///         pdev: &platform::Device<Core>,
895 ///         _id_info: Option<&Self::IdInfo>,
896 ///     ) -> impl PinInit<Self, Error> {
897 ///         cpufreq::Registration::<SampleDriver>::new_foreign_owned(pdev.as_ref())?;
898 ///         Ok(Self {})
899 ///     }
900 /// }
901 /// ```
902 #[repr(transparent)]
903 pub struct Registration<T: Driver>(KBox<UnsafeCell<bindings::cpufreq_driver>>, PhantomData<T>);
904 
905 /// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between threads
906 /// or CPUs, so it is safe to share it.
907 unsafe impl<T: Driver> Sync for Registration<T> {}
908 
909 #[allow(clippy::non_send_fields_in_send_ty)]
910 /// SAFETY: Registration with and unregistration from the cpufreq subsystem can happen from any
911 /// thread.
912 unsafe impl<T: Driver> Send for Registration<T> {}
913 
914 impl<T: Driver> Registration<T> {
915     const VTABLE: bindings::cpufreq_driver = bindings::cpufreq_driver {
916         name: Self::copy_name(T::NAME),
917         boost_enabled: T::BOOST_ENABLED,
918         flags: T::FLAGS,
919 
920         // Initialize mandatory callbacks.
921         init: Some(Self::init_callback),
922         verify: Some(Self::verify_callback),
923 
924         // Initialize optional callbacks based on the traits of `T`.
925         setpolicy: if T::HAS_SETPOLICY {
926             Some(Self::setpolicy_callback)
927         } else {
928             None
929         },
930         target: if T::HAS_TARGET {
931             Some(Self::target_callback)
932         } else {
933             None
934         },
935         target_index: if T::HAS_TARGET_INDEX {
936             Some(Self::target_index_callback)
937         } else {
938             None
939         },
940         fast_switch: if T::HAS_FAST_SWITCH {
941             Some(Self::fast_switch_callback)
942         } else {
943             None
944         },
945         adjust_perf: if T::HAS_ADJUST_PERF {
946             Some(Self::adjust_perf_callback)
947         } else {
948             None
949         },
950         get_intermediate: if T::HAS_GET_INTERMEDIATE {
951             Some(Self::get_intermediate_callback)
952         } else {
953             None
954         },
955         target_intermediate: if T::HAS_TARGET_INTERMEDIATE {
956             Some(Self::target_intermediate_callback)
957         } else {
958             None
959         },
960         get: if T::HAS_GET {
961             Some(Self::get_callback)
962         } else {
963             None
964         },
965         update_limits: if T::HAS_UPDATE_LIMITS {
966             Some(Self::update_limits_callback)
967         } else {
968             None
969         },
970         bios_limit: if T::HAS_BIOS_LIMIT {
971             Some(Self::bios_limit_callback)
972         } else {
973             None
974         },
975         online: if T::HAS_ONLINE {
976             Some(Self::online_callback)
977         } else {
978             None
979         },
980         offline: if T::HAS_OFFLINE {
981             Some(Self::offline_callback)
982         } else {
983             None
984         },
985         exit: if T::HAS_EXIT {
986             Some(Self::exit_callback)
987         } else {
988             None
989         },
990         suspend: if T::HAS_SUSPEND {
991             Some(Self::suspend_callback)
992         } else {
993             None
994         },
995         resume: if T::HAS_RESUME {
996             Some(Self::resume_callback)
997         } else {
998             None
999         },
1000         ready: if T::HAS_READY {
1001             Some(Self::ready_callback)
1002         } else {
1003             None
1004         },
1005         set_boost: if T::HAS_SET_BOOST {
1006             Some(Self::set_boost_callback)
1007         } else {
1008             None
1009         },
1010         register_em: if T::HAS_REGISTER_EM {
1011             Some(Self::register_em_callback)
1012         } else {
1013             None
1014         },
1015         ..pin_init::zeroed()
1016     };
1017 
1018     // Always inline to optimize out error path of `build_assert`.
1019     #[inline(always)]
1020     const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] {
1021         let src = name.to_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::register`] and will be dropped, once the
1050     /// device is detached.
1051     pub fn new_foreign_owned(dev: &Device<Bound>) -> Result
1052     where
1053         T: 'static,
1054     {
1055         devres::register(dev, Self::new()?, GFP_KERNEL)
1056     }
1057 }
1058 
1059 /// CPU frequency driver callbacks.
1060 impl<T: Driver> Registration<T> {
1061     /// Driver's `init` callback.
1062     ///
1063     /// # Safety
1064     ///
1065     /// - This function may only be called from the cpufreq C infrastructure.
1066     /// - The pointer arguments must be valid pointers.
1067     unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1068         from_result(|| {
1069             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1070             // lifetime of `policy`.
1071             let policy = unsafe { Policy::from_raw_mut(ptr) };
1072 
1073             let data = T::init(policy)?;
1074             policy.set_data(data)?;
1075             Ok(0)
1076         })
1077     }
1078 
1079     /// Driver's `exit` callback.
1080     ///
1081     /// # Safety
1082     ///
1083     /// - This function may only be called from the cpufreq C infrastructure.
1084     /// - The pointer arguments must be valid pointers.
1085     unsafe extern "C" fn exit_callback(ptr: *mut bindings::cpufreq_policy) {
1086         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1087         // lifetime of `policy`.
1088         let policy = unsafe { Policy::from_raw_mut(ptr) };
1089 
1090         let data = policy.clear_data();
1091         let _ = T::exit(policy, data);
1092     }
1093 
1094     /// Driver's `online` callback.
1095     ///
1096     /// # Safety
1097     ///
1098     /// - This function may only be called from the cpufreq C infrastructure.
1099     /// - The pointer arguments must be valid pointers.
1100     unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1101         from_result(|| {
1102             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1103             // lifetime of `policy`.
1104             let policy = unsafe { Policy::from_raw_mut(ptr) };
1105             T::online(policy).map(|()| 0)
1106         })
1107     }
1108 
1109     /// Driver's `offline` callback.
1110     ///
1111     /// # Safety
1112     ///
1113     /// - This function may only be called from the cpufreq C infrastructure.
1114     /// - The pointer arguments must be valid pointers.
1115     unsafe extern "C" fn offline_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1116         from_result(|| {
1117             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1118             // lifetime of `policy`.
1119             let policy = unsafe { Policy::from_raw_mut(ptr) };
1120             T::offline(policy).map(|()| 0)
1121         })
1122     }
1123 
1124     /// Driver's `suspend` callback.
1125     ///
1126     /// # Safety
1127     ///
1128     /// - This function may only be called from the cpufreq C infrastructure.
1129     /// - The pointer arguments must be valid pointers.
1130     unsafe extern "C" fn suspend_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1131         from_result(|| {
1132             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1133             // lifetime of `policy`.
1134             let policy = unsafe { Policy::from_raw_mut(ptr) };
1135             T::suspend(policy).map(|()| 0)
1136         })
1137     }
1138 
1139     /// Driver's `resume` callback.
1140     ///
1141     /// # Safety
1142     ///
1143     /// - This function may only be called from the cpufreq C infrastructure.
1144     /// - The pointer arguments must be valid pointers.
1145     unsafe extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1146         from_result(|| {
1147             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1148             // lifetime of `policy`.
1149             let policy = unsafe { Policy::from_raw_mut(ptr) };
1150             T::resume(policy).map(|()| 0)
1151         })
1152     }
1153 
1154     /// Driver's `ready` callback.
1155     ///
1156     /// # Safety
1157     ///
1158     /// - This function may only be called from the cpufreq C infrastructure.
1159     /// - The pointer arguments must be valid pointers.
1160     unsafe extern "C" fn ready_callback(ptr: *mut bindings::cpufreq_policy) {
1161         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1162         // lifetime of `policy`.
1163         let policy = unsafe { Policy::from_raw_mut(ptr) };
1164         T::ready(policy);
1165     }
1166 
1167     /// Driver's `verify` callback.
1168     ///
1169     /// # Safety
1170     ///
1171     /// - This function may only be called from the cpufreq C infrastructure.
1172     /// - The pointer arguments must be valid pointers.
1173     unsafe extern "C" fn verify_callback(ptr: *mut bindings::cpufreq_policy_data) -> c_int {
1174         from_result(|| {
1175             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1176             // lifetime of `policy`.
1177             let data = unsafe { PolicyData::from_raw_mut(ptr) };
1178             T::verify(data).map(|()| 0)
1179         })
1180     }
1181 
1182     /// Driver's `setpolicy` callback.
1183     ///
1184     /// # Safety
1185     ///
1186     /// - This function may only be called from the cpufreq C infrastructure.
1187     /// - The pointer arguments must be valid pointers.
1188     unsafe extern "C" fn setpolicy_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
1189         from_result(|| {
1190             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1191             // lifetime of `policy`.
1192             let policy = unsafe { Policy::from_raw_mut(ptr) };
1193             T::setpolicy(policy).map(|()| 0)
1194         })
1195     }
1196 
1197     /// Driver's `target` callback.
1198     ///
1199     /// # Safety
1200     ///
1201     /// - This function may only be called from the cpufreq C infrastructure.
1202     /// - The pointer arguments must be valid pointers.
1203     unsafe extern "C" fn target_callback(
1204         ptr: *mut bindings::cpufreq_policy,
1205         target_freq: c_uint,
1206         relation: c_uint,
1207     ) -> c_int {
1208         from_result(|| {
1209             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1210             // lifetime of `policy`.
1211             let policy = unsafe { Policy::from_raw_mut(ptr) };
1212             T::target(policy, target_freq, Relation::new(relation)?).map(|()| 0)
1213         })
1214     }
1215 
1216     /// Driver's `target_index` callback.
1217     ///
1218     /// # Safety
1219     ///
1220     /// - This function may only be called from the cpufreq C infrastructure.
1221     /// - The pointer arguments must be valid pointers.
1222     unsafe extern "C" fn target_index_callback(
1223         ptr: *mut bindings::cpufreq_policy,
1224         index: c_uint,
1225     ) -> c_int {
1226         from_result(|| {
1227             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1228             // lifetime of `policy`.
1229             let policy = unsafe { Policy::from_raw_mut(ptr) };
1230 
1231             // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1232             // frequency table.
1233             let index = unsafe { TableIndex::new(index as usize) };
1234 
1235             T::target_index(policy, index).map(|()| 0)
1236         })
1237     }
1238 
1239     /// Driver's `fast_switch` callback.
1240     ///
1241     /// # Safety
1242     ///
1243     /// - This function may only be called from the cpufreq C infrastructure.
1244     /// - The pointer arguments must be valid pointers.
1245     unsafe extern "C" fn fast_switch_callback(
1246         ptr: *mut bindings::cpufreq_policy,
1247         target_freq: c_uint,
1248     ) -> c_uint {
1249         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1250         // lifetime of `policy`.
1251         let policy = unsafe { Policy::from_raw_mut(ptr) };
1252         T::fast_switch(policy, target_freq)
1253     }
1254 
1255     /// Driver's `adjust_perf` callback.
1256     ///
1257     /// # Safety
1258     ///
1259     /// - This function may only be called from the cpufreq C infrastructure.
1260     unsafe extern "C" fn adjust_perf_callback(
1261         cpu: c_uint,
1262         min_perf: c_ulong,
1263         target_perf: c_ulong,
1264         capacity: c_ulong,
1265     ) {
1266         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1267         let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
1268 
1269         if let Ok(mut policy) = PolicyCpu::from_cpu(cpu_id) {
1270             T::adjust_perf(&mut policy, min_perf, target_perf, capacity);
1271         }
1272     }
1273 
1274     /// Driver's `get_intermediate` callback.
1275     ///
1276     /// # Safety
1277     ///
1278     /// - This function may only be called from the cpufreq C infrastructure.
1279     /// - The pointer arguments must be valid pointers.
1280     unsafe extern "C" fn get_intermediate_callback(
1281         ptr: *mut bindings::cpufreq_policy,
1282         index: c_uint,
1283     ) -> c_uint {
1284         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1285         // lifetime of `policy`.
1286         let policy = unsafe { Policy::from_raw_mut(ptr) };
1287 
1288         // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1289         // frequency table.
1290         let index = unsafe { TableIndex::new(index as usize) };
1291 
1292         T::get_intermediate(policy, index)
1293     }
1294 
1295     /// Driver's `target_intermediate` callback.
1296     ///
1297     /// # Safety
1298     ///
1299     /// - This function may only be called from the cpufreq C infrastructure.
1300     /// - The pointer arguments must be valid pointers.
1301     unsafe extern "C" fn target_intermediate_callback(
1302         ptr: *mut bindings::cpufreq_policy,
1303         index: c_uint,
1304     ) -> c_int {
1305         from_result(|| {
1306             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1307             // lifetime of `policy`.
1308             let policy = unsafe { Policy::from_raw_mut(ptr) };
1309 
1310             // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1311             // frequency table.
1312             let index = unsafe { TableIndex::new(index as usize) };
1313 
1314             T::target_intermediate(policy, index).map(|()| 0)
1315         })
1316     }
1317 
1318     /// Driver's `get` callback.
1319     ///
1320     /// # Safety
1321     ///
1322     /// - This function may only be called from the cpufreq C infrastructure.
1323     unsafe extern "C" fn get_callback(cpu: c_uint) -> c_uint {
1324         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1325         let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
1326 
1327         PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
1328     }
1329 
1330     /// Driver's `update_limit` callback.
1331     ///
1332     /// # Safety
1333     ///
1334     /// - This function may only be called from the cpufreq C infrastructure.
1335     /// - The pointer arguments must be valid pointers.
1336     unsafe extern "C" fn update_limits_callback(ptr: *mut bindings::cpufreq_policy) {
1337         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1338         // lifetime of `policy`.
1339         let policy = unsafe { Policy::from_raw_mut(ptr) };
1340         T::update_limits(policy);
1341     }
1342 
1343     /// Driver's `bios_limit` callback.
1344     ///
1345     /// # Safety
1346     ///
1347     /// - This function may only be called from the cpufreq C infrastructure.
1348     /// - The pointer arguments must be valid pointers.
1349     unsafe extern "C" fn bios_limit_callback(cpu: c_int, limit: *mut c_uint) -> c_int {
1350         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1351         let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) };
1352 
1353         from_result(|| {
1354             let mut policy = PolicyCpu::from_cpu(cpu_id)?;
1355 
1356             // SAFETY: `limit` is guaranteed by the C code to be valid.
1357             T::bios_limit(&mut policy, &mut (unsafe { *limit })).map(|()| 0)
1358         })
1359     }
1360 
1361     /// Driver's `set_boost` callback.
1362     ///
1363     /// # Safety
1364     ///
1365     /// - This function may only be called from the cpufreq C infrastructure.
1366     /// - The pointer arguments must be valid pointers.
1367     unsafe extern "C" fn set_boost_callback(
1368         ptr: *mut bindings::cpufreq_policy,
1369         state: c_int,
1370     ) -> c_int {
1371         from_result(|| {
1372             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1373             // lifetime of `policy`.
1374             let policy = unsafe { Policy::from_raw_mut(ptr) };
1375             T::set_boost(policy, state).map(|()| 0)
1376         })
1377     }
1378 
1379     /// Driver's `register_em` callback.
1380     ///
1381     /// # Safety
1382     ///
1383     /// - This function may only be called from the cpufreq C infrastructure.
1384     /// - The pointer arguments must be valid pointers.
1385     unsafe extern "C" fn register_em_callback(ptr: *mut bindings::cpufreq_policy) {
1386         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1387         // lifetime of `policy`.
1388         let policy = unsafe { Policy::from_raw_mut(ptr) };
1389         T::register_em(policy);
1390     }
1391 }
1392 
1393 impl<T: Driver> Drop for Registration<T> {
1394     /// Unregisters with the cpufreq core.
1395     fn drop(&mut self) {
1396         // SAFETY: `self.0` is guaranteed to be valid for the lifetime of `Registration`.
1397         unsafe { bindings::cpufreq_unregister_driver(self.0.get_mut()) };
1398     }
1399 }
1400