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