xref: /linux/rust/kernel/cpufreq.rs (revision f688b599d711d169b22e99f2d055847d66c4e0d3)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! CPU frequency scaling.
4 //!
5 //! This module provides rust abstractions for interacting with the cpufreq subsystem.
6 //!
7 //! C header: [`include/linux/cpufreq.h`](srctree/include/linux/cpufreq.h)
8 //!
9 //! Reference: <https://docs.kernel.org/admin-guide/pm/cpufreq.html>
10 
11 use crate::{
12     clk::Hertz,
13     cpu::CpuId,
14     cpumask,
15     device::{Bound, Device},
16     devres::Devres,
17     error::{code::*, from_err_ptr, from_result, to_result, Result, VTABLE_DEFAULT_ERROR},
18     ffi::{c_char, c_ulong},
19     prelude::*,
20     types::ForeignOwnable,
21     types::Opaque,
22 };
23 
24 #[cfg(CONFIG_COMMON_CLK)]
25 use crate::clk::Clk;
26 
27 use core::{
28     cell::UnsafeCell,
29     marker::PhantomData,
30     mem::MaybeUninit,
31     ops::{Deref, DerefMut},
32     pin::Pin,
33     ptr,
34 };
35 
36 use macros::vtable;
37 
38 /// Maximum length of CPU frequency driver's name.
39 const CPUFREQ_NAME_LEN: usize = bindings::CPUFREQ_NAME_LEN as usize;
40 
41 /// Default transition latency value in nanoseconds.
42 pub const ETERNAL_LATENCY_NS: u32 = bindings::CPUFREQ_ETERNAL as u32;
43 
44 /// CPU frequency driver flags.
45 pub mod flags {
46     /// Driver needs to update internal limits even if frequency remains unchanged.
47     pub const NEED_UPDATE_LIMITS: u16 = 1 << 0;
48 
49     /// Platform where constants like `loops_per_jiffy` are unaffected by frequency changes.
50     pub const CONST_LOOPS: u16 = 1 << 1;
51 
52     /// Register driver as a thermal cooling device automatically.
53     pub const IS_COOLING_DEV: u16 = 1 << 2;
54 
55     /// Supports multiple clock domains with per-policy governors in `cpu/cpuN/cpufreq/`.
56     pub const HAVE_GOVERNOR_PER_POLICY: u16 = 1 << 3;
57 
58     /// Allows post-change notifications outside of the `target()` routine.
59     pub const ASYNC_NOTIFICATION: u16 = 1 << 4;
60 
61     /// Ensure CPU starts at a valid frequency from the driver's freq-table.
62     pub const NEED_INITIAL_FREQ_CHECK: u16 = 1 << 5;
63 
64     /// Disallow governors with `dynamic_switching` capability.
65     pub const NO_AUTO_DYNAMIC_SWITCHING: u16 = 1 << 6;
66 }
67 
68 /// Relations from the C code.
69 const CPUFREQ_RELATION_L: u32 = 0;
70 const CPUFREQ_RELATION_H: u32 = 1;
71 const CPUFREQ_RELATION_C: u32 = 2;
72 
73 /// Can be used with any of the above values.
74 const CPUFREQ_RELATION_E: u32 = 1 << 2;
75 
76 /// CPU frequency selection relations.
77 ///
78 /// CPU frequency selection relations, each optionally marked as "efficient".
79 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
80 pub enum Relation {
81     /// Select the lowest frequency at or above target.
82     Low(bool),
83     /// Select the highest frequency below or at target.
84     High(bool),
85     /// Select the closest frequency to the target.
86     Close(bool),
87 }
88 
89 impl Relation {
90     // Construct from a C-compatible `u32` value.
new(val: u32) -> Result<Self>91     fn new(val: u32) -> Result<Self> {
92         let efficient = val & CPUFREQ_RELATION_E != 0;
93 
94         Ok(match val & !CPUFREQ_RELATION_E {
95             CPUFREQ_RELATION_L => Self::Low(efficient),
96             CPUFREQ_RELATION_H => Self::High(efficient),
97             CPUFREQ_RELATION_C => Self::Close(efficient),
98             _ => return Err(EINVAL),
99         })
100     }
101 }
102 
103 impl From<Relation> for u32 {
104     // Convert to a C-compatible `u32` value.
from(rel: Relation) -> Self105     fn from(rel: Relation) -> Self {
106         let (mut val, efficient) = match rel {
107             Relation::Low(e) => (CPUFREQ_RELATION_L, e),
108             Relation::High(e) => (CPUFREQ_RELATION_H, e),
109             Relation::Close(e) => (CPUFREQ_RELATION_C, e),
110         };
111 
112         if efficient {
113             val |= CPUFREQ_RELATION_E;
114         }
115 
116         val
117     }
118 }
119 
120 /// Policy data.
121 ///
122 /// Rust abstraction for the C `struct cpufreq_policy_data`.
123 ///
124 /// # Invariants
125 ///
126 /// A [`PolicyData`] instance always corresponds to a valid C `struct cpufreq_policy_data`.
127 ///
128 /// The callers must ensure that the `struct cpufreq_policy_data` is valid for access and remains
129 /// valid for the lifetime of the returned reference.
130 #[repr(transparent)]
131 pub struct PolicyData(Opaque<bindings::cpufreq_policy_data>);
132 
133 impl PolicyData {
134     /// Creates a mutable reference to an existing `struct cpufreq_policy_data` pointer.
135     ///
136     /// # Safety
137     ///
138     /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime
139     /// of the returned reference.
140     #[inline]
from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy_data) -> &'a mut Self141     pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy_data) -> &'a mut Self {
142         // SAFETY: Guaranteed by the safety requirements of the function.
143         //
144         // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the
145         // lifetime of the returned reference.
146         unsafe { &mut *ptr.cast() }
147     }
148 
149     /// Returns a raw pointer to the underlying C `cpufreq_policy_data`.
150     #[inline]
as_raw(&self) -> *mut bindings::cpufreq_policy_data151     pub fn as_raw(&self) -> *mut bindings::cpufreq_policy_data {
152         let this: *const Self = self;
153         this.cast_mut().cast()
154     }
155 
156     /// Wrapper for `cpufreq_generic_frequency_table_verify`.
157     #[inline]
generic_verify(&self) -> Result158     pub fn generic_verify(&self) -> Result {
159         // SAFETY: By the type invariant, the pointer stored in `self` is valid.
160         to_result(unsafe { bindings::cpufreq_generic_frequency_table_verify(self.as_raw()) })
161     }
162 }
163 
164 /// The frequency table index.
165 ///
166 /// Represents index with a frequency table.
167 ///
168 /// # Invariants
169 ///
170 /// The index must correspond to a valid entry in the [`Table`] it is used for.
171 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
172 pub struct TableIndex(usize);
173 
174 impl TableIndex {
175     /// Creates an instance of [`TableIndex`].
176     ///
177     /// # Safety
178     ///
179     /// The caller must ensure that `index` correspond to a valid entry in the [`Table`] it is used
180     /// for.
new(index: usize) -> Self181     pub unsafe fn new(index: usize) -> Self {
182         // INVARIANT: The caller ensures that `index` correspond to a valid entry in the [`Table`].
183         Self(index)
184     }
185 }
186 
187 impl From<TableIndex> for usize {
188     #[inline]
from(index: TableIndex) -> Self189     fn from(index: TableIndex) -> Self {
190         index.0
191     }
192 }
193 
194 /// CPU frequency table.
195 ///
196 /// Rust abstraction for the C `struct cpufreq_frequency_table`.
197 ///
198 /// # Invariants
199 ///
200 /// A [`Table`] instance always corresponds to a valid C `struct cpufreq_frequency_table`.
201 ///
202 /// The callers must ensure that the `struct cpufreq_frequency_table` is valid for access and
203 /// remains valid for the lifetime of the returned reference.
204 ///
205 /// ## Examples
206 ///
207 /// The following example demonstrates how to read a frequency value from [`Table`].
208 ///
209 /// ```
210 /// use kernel::cpufreq::{Policy, TableIndex};
211 ///
212 /// fn show_freq(policy: &Policy) -> Result {
213 ///     let table = policy.freq_table()?;
214 ///
215 ///     // SAFETY: Index is a valid entry in the table.
216 ///     let index = unsafe { TableIndex::new(0) };
217 ///
218 ///     pr_info!("The frequency at index 0 is: {:?}\n", table.freq(index)?);
219 ///     pr_info!("The flags at index 0 is: {}\n", table.flags(index));
220 ///     pr_info!("The data at index 0 is: {}\n", table.data(index));
221 ///     Ok(())
222 /// }
223 /// ```
224 #[repr(transparent)]
225 pub struct Table(Opaque<bindings::cpufreq_frequency_table>);
226 
227 impl Table {
228     /// Creates a reference to an existing C `struct cpufreq_frequency_table` pointer.
229     ///
230     /// # Safety
231     ///
232     /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime
233     /// of the returned reference.
234     #[inline]
from_raw<'a>(ptr: *const bindings::cpufreq_frequency_table) -> &'a Self235     pub unsafe fn from_raw<'a>(ptr: *const bindings::cpufreq_frequency_table) -> &'a Self {
236         // SAFETY: Guaranteed by the safety requirements of the function.
237         //
238         // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the
239         // lifetime of the returned reference.
240         unsafe { &*ptr.cast() }
241     }
242 
243     /// Returns the raw mutable pointer to the C `struct cpufreq_frequency_table`.
244     #[inline]
as_raw(&self) -> *mut bindings::cpufreq_frequency_table245     pub fn as_raw(&self) -> *mut bindings::cpufreq_frequency_table {
246         let this: *const Self = self;
247         this.cast_mut().cast()
248     }
249 
250     /// Returns frequency at `index` in the [`Table`].
251     #[inline]
freq(&self, index: TableIndex) -> Result<Hertz>252     pub fn freq(&self, index: TableIndex) -> Result<Hertz> {
253         // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
254         // guaranteed to be valid by its safety requirements.
255         Ok(Hertz::from_khz(unsafe {
256             (*self.as_raw().add(index.into())).frequency.try_into()?
257         }))
258     }
259 
260     /// Returns flags at `index` in the [`Table`].
261     #[inline]
flags(&self, index: TableIndex) -> u32262     pub fn flags(&self, index: TableIndex) -> u32 {
263         // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
264         // guaranteed to be valid by its safety requirements.
265         unsafe { (*self.as_raw().add(index.into())).flags }
266     }
267 
268     /// Returns data at `index` in the [`Table`].
269     #[inline]
data(&self, index: TableIndex) -> u32270     pub fn data(&self, index: TableIndex) -> u32 {
271         // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
272         // guaranteed to be valid by its safety requirements.
273         unsafe { (*self.as_raw().add(index.into())).driver_data }
274     }
275 }
276 
277 /// CPU frequency table owned and pinned in memory, created from a [`TableBuilder`].
278 pub struct TableBox {
279     entries: Pin<KVec<bindings::cpufreq_frequency_table>>,
280 }
281 
282 impl TableBox {
283     /// Constructs a new [`TableBox`] from a [`KVec`] of entries.
284     ///
285     /// # Errors
286     ///
287     /// Returns `EINVAL` if the entries list is empty.
288     #[inline]
new(entries: KVec<bindings::cpufreq_frequency_table>) -> Result<Self>289     fn new(entries: KVec<bindings::cpufreq_frequency_table>) -> Result<Self> {
290         if entries.is_empty() {
291             return Err(EINVAL);
292         }
293 
294         Ok(Self {
295             // Pin the entries to memory, since we are passing its pointer to the C code.
296             entries: Pin::new(entries),
297         })
298     }
299 
300     /// Returns a raw pointer to the underlying C `cpufreq_frequency_table`.
301     #[inline]
as_raw(&self) -> *const bindings::cpufreq_frequency_table302     fn as_raw(&self) -> *const bindings::cpufreq_frequency_table {
303         // The pointer is valid until the table gets dropped.
304         self.entries.as_ptr()
305     }
306 }
307 
308 impl Deref for TableBox {
309     type Target = Table;
310 
deref(&self) -> &Self::Target311     fn deref(&self) -> &Self::Target {
312         // SAFETY: The caller owns TableBox, it is safe to deref.
313         unsafe { Self::Target::from_raw(self.as_raw()) }
314     }
315 }
316 
317 /// CPU frequency table builder.
318 ///
319 /// This is used by the CPU frequency drivers to build a frequency table dynamically.
320 ///
321 /// ## Examples
322 ///
323 /// The following example demonstrates how to create a CPU frequency table.
324 ///
325 /// ```
326 /// use kernel::cpufreq::{TableBuilder, TableIndex};
327 /// use kernel::clk::Hertz;
328 ///
329 /// let mut builder = TableBuilder::new();
330 ///
331 /// // Adds few entries to the table.
332 /// builder.add(Hertz::from_mhz(700), 0, 1).unwrap();
333 /// builder.add(Hertz::from_mhz(800), 2, 3).unwrap();
334 /// builder.add(Hertz::from_mhz(900), 4, 5).unwrap();
335 /// builder.add(Hertz::from_ghz(1), 6, 7).unwrap();
336 ///
337 /// let table = builder.to_table().unwrap();
338 ///
339 /// // SAFETY: Index values correspond to valid entries in the table.
340 /// let (index0, index2) = unsafe { (TableIndex::new(0), TableIndex::new(2)) };
341 ///
342 /// assert_eq!(table.freq(index0), Ok(Hertz::from_mhz(700)));
343 /// assert_eq!(table.flags(index0), 0);
344 /// assert_eq!(table.data(index0), 1);
345 ///
346 /// assert_eq!(table.freq(index2), Ok(Hertz::from_mhz(900)));
347 /// assert_eq!(table.flags(index2), 4);
348 /// assert_eq!(table.data(index2), 5);
349 /// ```
350 #[derive(Default)]
351 #[repr(transparent)]
352 pub struct TableBuilder {
353     entries: KVec<bindings::cpufreq_frequency_table>,
354 }
355 
356 impl TableBuilder {
357     /// Creates a new instance of [`TableBuilder`].
358     #[inline]
new() -> Self359     pub fn new() -> Self {
360         Self {
361             entries: KVec::new(),
362         }
363     }
364 
365     /// Adds a new entry to the table.
add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result366     pub fn add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result {
367         // Adds the new entry at the end of the vector.
368         Ok(self.entries.push(
369             bindings::cpufreq_frequency_table {
370                 flags,
371                 driver_data,
372                 frequency: freq.as_khz() as u32,
373             },
374             GFP_KERNEL,
375         )?)
376     }
377 
378     /// Consumes the [`TableBuilder`] and returns [`TableBox`].
to_table(mut self) -> Result<TableBox>379     pub fn to_table(mut self) -> Result<TableBox> {
380         // Add last entry to the table.
381         self.add(Hertz(c_ulong::MAX), 0, 0)?;
382 
383         TableBox::new(self.entries)
384     }
385 }
386 
387 /// CPU frequency policy.
388 ///
389 /// Rust abstraction for the C `struct cpufreq_policy`.
390 ///
391 /// # Invariants
392 ///
393 /// A [`Policy`] instance always corresponds to a valid C `struct cpufreq_policy`.
394 ///
395 /// The callers must ensure that the `struct cpufreq_policy` is valid for access and remains valid
396 /// for the lifetime of the returned reference.
397 ///
398 /// ## Examples
399 ///
400 /// The following example demonstrates how to create a CPU frequency table.
401 ///
402 /// ```
403 /// use kernel::cpufreq::{ETERNAL_LATENCY_NS, Policy};
404 ///
405 /// fn update_policy(policy: &mut Policy) {
406 ///     policy
407 ///         .set_dvfs_possible_from_any_cpu(true)
408 ///         .set_fast_switch_possible(true)
409 ///         .set_transition_latency_ns(ETERNAL_LATENCY_NS);
410 ///
411 ///     pr_info!("The policy details are: {:?}\n", (policy.cpu(), policy.cur()));
412 /// }
413 /// ```
414 #[repr(transparent)]
415 pub struct Policy(Opaque<bindings::cpufreq_policy>);
416 
417 impl Policy {
418     /// Creates a reference to an existing `struct cpufreq_policy` pointer.
419     ///
420     /// # Safety
421     ///
422     /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime
423     /// of the returned reference.
424     #[inline]
from_raw<'a>(ptr: *const bindings::cpufreq_policy) -> &'a Self425     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]
from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy) -> &'a mut Self440     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]
as_raw(&self) -> *mut bindings::cpufreq_policy450     fn as_raw(&self) -> *mut bindings::cpufreq_policy {
451         let this: *const Self = self;
452         this.cast_mut().cast()
453     }
454 
455     #[inline]
as_ref(&self) -> &bindings::cpufreq_policy456     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]
as_mut_ref(&mut self) -> &mut bindings::cpufreq_policy462     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]
cpu(&self) -> CpuId469     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]
min(&self) -> Hertz476     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]
set_min(&mut self, min: Hertz) -> &mut Self482     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]
max(&self) -> Hertz489     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]
set_max(&mut self, max: Hertz) -> &mut Self495     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]
cur(&self) -> Hertz502     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]
suspend_freq(&self) -> Hertz508     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]
set_suspend_freq(&mut self, freq: Hertz) -> &mut Self514     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]
generic_suspend(&mut self) -> Result521     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]
generic_get(&self) -> Result<u32>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]
register_em_opp(&mut self)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]
cpus(&mut self) -> &mut cpumask::Cpumask543     pub fn cpus(&mut self) -> &mut cpumask::Cpumask {
544         // SAFETY: The pointer to `cpus` is valid for writing and remains valid for the lifetime of
545         // the returned reference.
546         unsafe { cpumask::CpumaskVar::as_mut_ref(&mut self.as_mut_ref().cpus) }
547     }
548 
549     /// Sets clock for the [`Policy`].
550     ///
551     /// # Safety
552     ///
553     /// The caller must guarantee that the returned [`Clk`] is not dropped while it is getting used
554     /// by the C code.
555     #[cfg(CONFIG_COMMON_CLK)]
set_clk(&mut self, dev: &Device, name: Option<&CStr>) -> Result<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]
set_dvfs_possible_from_any_cpu(&mut self, val: bool) -> &mut Self564     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]
fast_switch_possible(&self) -> bool571     pub fn fast_switch_possible(&self) -> bool {
572         self.as_ref().fast_switch_possible
573     }
574 
575     /// Enables / disables fast frequency switching.
576     #[inline]
set_fast_switch_possible(&mut self, val: bool) -> &mut Self577     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]
set_transition_latency_ns(&mut self, latency_ns: u32) -> &mut Self584     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]
set_cpuinfo_min_freq(&mut self, min_freq: Hertz) -> &mut Self591     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]
set_cpuinfo_max_freq(&mut self, max_freq: Hertz) -> &mut Self598     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]
set_transition_delay_us(&mut self, transition_delay_us: u32) -> &mut Self606     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`].
freq_table(&self) -> Result<&Table>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]
set_freq_table(&mut self, table: &Table) -> &mut Self629     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.
data<T: ForeignOwnable>(&mut self) -> Option<<T>::Borrowed<'_>>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.
set_data<T: ForeignOwnable>(&mut self, data: T) -> Result649     fn set_data<T: ForeignOwnable>(&mut self, data: T) -> Result {
650         if self.as_ref().driver_data.is_null() {
651             // Transfer the ownership of the data to the foreign interface.
652             self.as_mut_ref().driver_data = <T as ForeignOwnable>::into_foreign(data) as _;
653             Ok(())
654         } else {
655             Err(EBUSY)
656         }
657     }
658 
659     /// Clears and returns ownership of the private data.
clear_data<T: ForeignOwnable>(&mut self) -> Option<T>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> {
from_cpu(cpu: CpuId) -> Result<Self>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 
deref(&self) -> &Self::Target698     fn deref(&self) -> &Self::Target {
699         self.0
700     }
701 }
702 
703 impl<'a> DerefMut for PolicyCpu<'a> {
deref_mut(&mut self) -> &mut Policy704     fn deref_mut(&mut self) -> &mut Policy {
705         self.0
706     }
707 }
708 
709 impl<'a> Drop for PolicyCpu<'a> {
drop(&mut self)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.
init(policy: &mut Policy) -> Result<Self::PData>739     fn init(policy: &mut Policy) -> Result<Self::PData>;
740 
741     /// Driver's `exit` callback.
exit(_policy: &mut Policy, _data: Option<Self::PData>) -> Result742     fn exit(_policy: &mut Policy, _data: Option<Self::PData>) -> Result {
743         build_error!(VTABLE_DEFAULT_ERROR)
744     }
745 
746     /// Driver's `online` callback.
online(_policy: &mut Policy) -> Result747     fn online(_policy: &mut Policy) -> Result {
748         build_error!(VTABLE_DEFAULT_ERROR)
749     }
750 
751     /// Driver's `offline` callback.
offline(_policy: &mut Policy) -> Result752     fn offline(_policy: &mut Policy) -> Result {
753         build_error!(VTABLE_DEFAULT_ERROR)
754     }
755 
756     /// Driver's `suspend` callback.
suspend(_policy: &mut Policy) -> Result757     fn suspend(_policy: &mut Policy) -> Result {
758         build_error!(VTABLE_DEFAULT_ERROR)
759     }
760 
761     /// Driver's `resume` callback.
resume(_policy: &mut Policy) -> Result762     fn resume(_policy: &mut Policy) -> Result {
763         build_error!(VTABLE_DEFAULT_ERROR)
764     }
765 
766     /// Driver's `ready` callback.
ready(_policy: &mut Policy)767     fn ready(_policy: &mut Policy) {
768         build_error!(VTABLE_DEFAULT_ERROR)
769     }
770 
771     /// Driver's `verify` callback.
verify(data: &mut PolicyData) -> Result772     fn verify(data: &mut PolicyData) -> Result;
773 
774     /// Driver's `setpolicy` callback.
setpolicy(_policy: &mut Policy) -> Result775     fn setpolicy(_policy: &mut Policy) -> Result {
776         build_error!(VTABLE_DEFAULT_ERROR)
777     }
778 
779     /// Driver's `target` callback.
target(_policy: &mut Policy, _target_freq: u32, _relation: Relation) -> Result780     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.
target_index(_policy: &mut Policy, _index: TableIndex) -> Result785     fn target_index(_policy: &mut Policy, _index: TableIndex) -> Result {
786         build_error!(VTABLE_DEFAULT_ERROR)
787     }
788 
789     /// Driver's `fast_switch` callback.
fast_switch(_policy: &mut Policy, _target_freq: u32) -> u32790     fn fast_switch(_policy: &mut Policy, _target_freq: u32) -> u32 {
791         build_error!(VTABLE_DEFAULT_ERROR)
792     }
793 
794     /// Driver's `adjust_perf` callback.
adjust_perf(_policy: &mut Policy, _min_perf: usize, _target_perf: usize, _capacity: usize)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.
get_intermediate(_policy: &mut Policy, _index: TableIndex) -> u32800     fn get_intermediate(_policy: &mut Policy, _index: TableIndex) -> u32 {
801         build_error!(VTABLE_DEFAULT_ERROR)
802     }
803 
804     /// Driver's `target_intermediate` callback.
target_intermediate(_policy: &mut Policy, _index: TableIndex) -> Result805     fn target_intermediate(_policy: &mut Policy, _index: TableIndex) -> Result {
806         build_error!(VTABLE_DEFAULT_ERROR)
807     }
808 
809     /// Driver's `get` callback.
get(_policy: &mut Policy) -> Result<u32>810     fn get(_policy: &mut Policy) -> Result<u32> {
811         build_error!(VTABLE_DEFAULT_ERROR)
812     }
813 
814     /// Driver's `update_limits` callback.
update_limits(_policy: &mut Policy)815     fn update_limits(_policy: &mut Policy) {
816         build_error!(VTABLE_DEFAULT_ERROR)
817     }
818 
819     /// Driver's `bios_limit` callback.
bios_limit(_policy: &mut Policy, _limit: &mut u32) -> Result820     fn bios_limit(_policy: &mut Policy, _limit: &mut u32) -> Result {
821         build_error!(VTABLE_DEFAULT_ERROR)
822     }
823 
824     /// Driver's `set_boost` callback.
set_boost(_policy: &mut Policy, _state: i32) -> Result825     fn set_boost(_policy: &mut Policy, _state: i32) -> Result {
826         build_error!(VTABLE_DEFAULT_ERROR)
827     }
828 
829     /// Driver's `register_em` callback.
register_em(_policy: &mut Policy)830     fn register_em(_policy: &mut Policy) {
831         build_error!(VTABLE_DEFAULT_ERROR)
832     }
833 }
834 
835 /// CPU frequency driver Registration.
836 ///
837 /// ## Examples
838 ///
839 /// The following example demonstrates how to register a cpufreq driver.
840 ///
841 /// ```
842 /// use kernel::{
843 ///     cpufreq,
844 ///     c_str,
845 ///     device::{Core, Device},
846 ///     macros::vtable,
847 ///     of, platform,
848 ///     sync::Arc,
849 /// };
850 /// struct SampleDevice;
851 ///
852 /// #[derive(Default)]
853 /// struct SampleDriver;
854 ///
855 /// #[vtable]
856 /// impl cpufreq::Driver for SampleDriver {
857 ///     const NAME: &'static CStr = c_str!("cpufreq-sample");
858 ///     const FLAGS: u16 = cpufreq::flags::NEED_INITIAL_FREQ_CHECK | cpufreq::flags::IS_COOLING_DEV;
859 ///     const BOOST_ENABLED: bool = true;
860 ///
861 ///     type PData = Arc<SampleDevice>;
862 ///
863 ///     fn init(policy: &mut cpufreq::Policy) -> Result<Self::PData> {
864 ///         // Initialize here
865 ///         Ok(Arc::new(SampleDevice, GFP_KERNEL)?)
866 ///     }
867 ///
868 ///     fn exit(_policy: &mut cpufreq::Policy, _data: Option<Self::PData>) -> Result {
869 ///         Ok(())
870 ///     }
871 ///
872 ///     fn suspend(policy: &mut cpufreq::Policy) -> Result {
873 ///         policy.generic_suspend()
874 ///     }
875 ///
876 ///     fn verify(data: &mut cpufreq::PolicyData) -> Result {
877 ///         data.generic_verify()
878 ///     }
879 ///
880 ///     fn target_index(policy: &mut cpufreq::Policy, index: cpufreq::TableIndex) -> Result {
881 ///         // Update CPU frequency
882 ///         Ok(())
883 ///     }
884 ///
885 ///     fn get(policy: &mut cpufreq::Policy) -> Result<u32> {
886 ///         policy.generic_get()
887 ///     }
888 /// }
889 ///
890 /// impl platform::Driver for SampleDriver {
891 ///     type IdInfo = ();
892 ///     const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
893 ///
894 ///     fn probe(
895 ///         pdev: &platform::Device<Core>,
896 ///         _id_info: Option<&Self::IdInfo>,
897 ///     ) -> Result<Pin<KBox<Self>>> {
898 ///         cpufreq::Registration::<SampleDriver>::new_foreign_owned(pdev.as_ref())?;
899 ///         Ok(KBox::new(Self {}, GFP_KERNEL)?.into())
900 ///     }
901 /// }
902 /// ```
903 #[repr(transparent)]
904 pub struct Registration<T: Driver>(KBox<UnsafeCell<bindings::cpufreq_driver>>, PhantomData<T>);
905 
906 /// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between threads
907 /// or CPUs, so it is safe to share it.
908 unsafe impl<T: Driver> Sync for Registration<T> {}
909 
910 #[allow(clippy::non_send_fields_in_send_ty)]
911 /// SAFETY: Registration with and unregistration from the cpufreq subsystem can happen from any
912 /// thread.
913 unsafe impl<T: Driver> Send for Registration<T> {}
914 
915 impl<T: Driver> Registration<T> {
916     const VTABLE: bindings::cpufreq_driver = bindings::cpufreq_driver {
917         name: Self::copy_name(T::NAME),
918         boost_enabled: T::BOOST_ENABLED,
919         flags: T::FLAGS,
920 
921         // Initialize mandatory callbacks.
922         init: Some(Self::init_callback),
923         verify: Some(Self::verify_callback),
924 
925         // Initialize optional callbacks based on the traits of `T`.
926         setpolicy: if T::HAS_SETPOLICY {
927             Some(Self::setpolicy_callback)
928         } else {
929             None
930         },
931         target: if T::HAS_TARGET {
932             Some(Self::target_callback)
933         } else {
934             None
935         },
936         target_index: if T::HAS_TARGET_INDEX {
937             Some(Self::target_index_callback)
938         } else {
939             None
940         },
941         fast_switch: if T::HAS_FAST_SWITCH {
942             Some(Self::fast_switch_callback)
943         } else {
944             None
945         },
946         adjust_perf: if T::HAS_ADJUST_PERF {
947             Some(Self::adjust_perf_callback)
948         } else {
949             None
950         },
951         get_intermediate: if T::HAS_GET_INTERMEDIATE {
952             Some(Self::get_intermediate_callback)
953         } else {
954             None
955         },
956         target_intermediate: if T::HAS_TARGET_INTERMEDIATE {
957             Some(Self::target_intermediate_callback)
958         } else {
959             None
960         },
961         get: if T::HAS_GET {
962             Some(Self::get_callback)
963         } else {
964             None
965         },
966         update_limits: if T::HAS_UPDATE_LIMITS {
967             Some(Self::update_limits_callback)
968         } else {
969             None
970         },
971         bios_limit: if T::HAS_BIOS_LIMIT {
972             Some(Self::bios_limit_callback)
973         } else {
974             None
975         },
976         online: if T::HAS_ONLINE {
977             Some(Self::online_callback)
978         } else {
979             None
980         },
981         offline: if T::HAS_OFFLINE {
982             Some(Self::offline_callback)
983         } else {
984             None
985         },
986         exit: if T::HAS_EXIT {
987             Some(Self::exit_callback)
988         } else {
989             None
990         },
991         suspend: if T::HAS_SUSPEND {
992             Some(Self::suspend_callback)
993         } else {
994             None
995         },
996         resume: if T::HAS_RESUME {
997             Some(Self::resume_callback)
998         } else {
999             None
1000         },
1001         ready: if T::HAS_READY {
1002             Some(Self::ready_callback)
1003         } else {
1004             None
1005         },
1006         set_boost: if T::HAS_SET_BOOST {
1007             Some(Self::set_boost_callback)
1008         } else {
1009             None
1010         },
1011         register_em: if T::HAS_REGISTER_EM {
1012             Some(Self::register_em_callback)
1013         } else {
1014             None
1015         },
1016         // SAFETY: All zeros is a valid value for `bindings::cpufreq_driver`.
1017         ..unsafe { MaybeUninit::zeroed().assume_init() }
1018     };
1019 
copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN]1020     const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] {
1021         let src = name.as_bytes_with_nul();
1022         let mut dst = [0; CPUFREQ_NAME_LEN];
1023 
1024         build_assert!(src.len() <= CPUFREQ_NAME_LEN);
1025 
1026         let mut i = 0;
1027         while i < src.len() {
1028             dst[i] = src[i];
1029             i += 1;
1030         }
1031 
1032         dst
1033     }
1034 
1035     /// Registers a CPU frequency driver with the cpufreq core.
new() -> Result<Self>1036     pub fn new() -> Result<Self> {
1037         // We can't use `&Self::VTABLE` directly because the cpufreq core modifies some fields in
1038         // the C `struct cpufreq_driver`, which requires a mutable reference.
1039         let mut drv = KBox::new(UnsafeCell::new(Self::VTABLE), GFP_KERNEL)?;
1040 
1041         // SAFETY: `drv` is guaranteed to be valid for the lifetime of `Registration`.
1042         to_result(unsafe { bindings::cpufreq_register_driver(drv.get_mut()) })?;
1043 
1044         Ok(Self(drv, PhantomData))
1045     }
1046 
1047     /// Same as [`Registration::new`], but does not return a [`Registration`] instance.
1048     ///
1049     /// Instead the [`Registration`] is owned by [`Devres`] and will be revoked / dropped, once the
1050     /// device is detached.
new_foreign_owned(dev: &Device<Bound>) -> Result1051     pub fn new_foreign_owned(dev: &Device<Bound>) -> Result {
1052         Devres::new_foreign_owned(dev, Self::new()?, GFP_KERNEL)
1053     }
1054 }
1055 
1056 /// CPU frequency driver callbacks.
1057 impl<T: Driver> Registration<T> {
1058     /// Driver's `init` callback.
1059     ///
1060     /// # Safety
1061     ///
1062     /// - This function may only be called from the cpufreq C infrastructure.
1063     /// - The pointer arguments must be valid pointers.
init_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int1064     unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int {
1065         from_result(|| {
1066             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1067             // lifetime of `policy`.
1068             let policy = unsafe { Policy::from_raw_mut(ptr) };
1069 
1070             let data = T::init(policy)?;
1071             policy.set_data(data)?;
1072             Ok(0)
1073         })
1074     }
1075 
1076     /// Driver's `exit` callback.
1077     ///
1078     /// # Safety
1079     ///
1080     /// - This function may only be called from the cpufreq C infrastructure.
1081     /// - The pointer arguments must be valid pointers.
exit_callback(ptr: *mut bindings::cpufreq_policy)1082     unsafe extern "C" fn exit_callback(ptr: *mut bindings::cpufreq_policy) {
1083         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1084         // lifetime of `policy`.
1085         let policy = unsafe { Policy::from_raw_mut(ptr) };
1086 
1087         let data = policy.clear_data();
1088         let _ = T::exit(policy, data);
1089     }
1090 
1091     /// Driver's `online` callback.
1092     ///
1093     /// # Safety
1094     ///
1095     /// - This function may only be called from the cpufreq C infrastructure.
1096     /// - The pointer arguments must be valid pointers.
online_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int1097     unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int {
1098         from_result(|| {
1099             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1100             // lifetime of `policy`.
1101             let policy = unsafe { Policy::from_raw_mut(ptr) };
1102             T::online(policy).map(|()| 0)
1103         })
1104     }
1105 
1106     /// Driver's `offline` callback.
1107     ///
1108     /// # Safety
1109     ///
1110     /// - This function may only be called from the cpufreq C infrastructure.
1111     /// - The pointer arguments must be valid pointers.
offline_callback( ptr: *mut bindings::cpufreq_policy, ) -> kernel::ffi::c_int1112     unsafe extern "C" fn offline_callback(
1113         ptr: *mut bindings::cpufreq_policy,
1114     ) -> kernel::ffi::c_int {
1115         from_result(|| {
1116             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1117             // lifetime of `policy`.
1118             let policy = unsafe { Policy::from_raw_mut(ptr) };
1119             T::offline(policy).map(|()| 0)
1120         })
1121     }
1122 
1123     /// Driver's `suspend` callback.
1124     ///
1125     /// # Safety
1126     ///
1127     /// - This function may only be called from the cpufreq C infrastructure.
1128     /// - The pointer arguments must be valid pointers.
suspend_callback( ptr: *mut bindings::cpufreq_policy, ) -> kernel::ffi::c_int1129     unsafe extern "C" fn suspend_callback(
1130         ptr: *mut bindings::cpufreq_policy,
1131     ) -> kernel::ffi::c_int {
1132         from_result(|| {
1133             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1134             // lifetime of `policy`.
1135             let policy = unsafe { Policy::from_raw_mut(ptr) };
1136             T::suspend(policy).map(|()| 0)
1137         })
1138     }
1139 
1140     /// Driver's `resume` callback.
1141     ///
1142     /// # Safety
1143     ///
1144     /// - This function may only be called from the cpufreq C infrastructure.
1145     /// - The pointer arguments must be valid pointers.
resume_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int1146     unsafe extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int {
1147         from_result(|| {
1148             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1149             // lifetime of `policy`.
1150             let policy = unsafe { Policy::from_raw_mut(ptr) };
1151             T::resume(policy).map(|()| 0)
1152         })
1153     }
1154 
1155     /// Driver's `ready` callback.
1156     ///
1157     /// # Safety
1158     ///
1159     /// - This function may only be called from the cpufreq C infrastructure.
1160     /// - The pointer arguments must be valid pointers.
ready_callback(ptr: *mut bindings::cpufreq_policy)1161     unsafe extern "C" fn ready_callback(ptr: *mut bindings::cpufreq_policy) {
1162         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1163         // lifetime of `policy`.
1164         let policy = unsafe { Policy::from_raw_mut(ptr) };
1165         T::ready(policy);
1166     }
1167 
1168     /// Driver's `verify` callback.
1169     ///
1170     /// # Safety
1171     ///
1172     /// - This function may only be called from the cpufreq C infrastructure.
1173     /// - The pointer arguments must be valid pointers.
verify_callback( ptr: *mut bindings::cpufreq_policy_data, ) -> kernel::ffi::c_int1174     unsafe extern "C" fn verify_callback(
1175         ptr: *mut bindings::cpufreq_policy_data,
1176     ) -> kernel::ffi::c_int {
1177         from_result(|| {
1178             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1179             // lifetime of `policy`.
1180             let data = unsafe { PolicyData::from_raw_mut(ptr) };
1181             T::verify(data).map(|()| 0)
1182         })
1183     }
1184 
1185     /// Driver's `setpolicy` callback.
1186     ///
1187     /// # Safety
1188     ///
1189     /// - This function may only be called from the cpufreq C infrastructure.
1190     /// - The pointer arguments must be valid pointers.
setpolicy_callback( ptr: *mut bindings::cpufreq_policy, ) -> kernel::ffi::c_int1191     unsafe extern "C" fn setpolicy_callback(
1192         ptr: *mut bindings::cpufreq_policy,
1193     ) -> kernel::ffi::c_int {
1194         from_result(|| {
1195             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1196             // lifetime of `policy`.
1197             let policy = unsafe { Policy::from_raw_mut(ptr) };
1198             T::setpolicy(policy).map(|()| 0)
1199         })
1200     }
1201 
1202     /// Driver's `target` callback.
1203     ///
1204     /// # Safety
1205     ///
1206     /// - This function may only be called from the cpufreq C infrastructure.
1207     /// - The pointer arguments must be valid pointers.
target_callback( ptr: *mut bindings::cpufreq_policy, target_freq: u32, relation: u32, ) -> kernel::ffi::c_int1208     unsafe extern "C" fn target_callback(
1209         ptr: *mut bindings::cpufreq_policy,
1210         target_freq: u32,
1211         relation: u32,
1212     ) -> kernel::ffi::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::target(policy, target_freq, Relation::new(relation)?).map(|()| 0)
1218         })
1219     }
1220 
1221     /// Driver's `target_index` 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.
target_index_callback( ptr: *mut bindings::cpufreq_policy, index: u32, ) -> kernel::ffi::c_int1227     unsafe extern "C" fn target_index_callback(
1228         ptr: *mut bindings::cpufreq_policy,
1229         index: u32,
1230     ) -> kernel::ffi::c_int {
1231         from_result(|| {
1232             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1233             // lifetime of `policy`.
1234             let policy = unsafe { Policy::from_raw_mut(ptr) };
1235 
1236             // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1237             // frequency table.
1238             let index = unsafe { TableIndex::new(index as usize) };
1239 
1240             T::target_index(policy, index).map(|()| 0)
1241         })
1242     }
1243 
1244     /// Driver's `fast_switch` callback.
1245     ///
1246     /// # Safety
1247     ///
1248     /// - This function may only be called from the cpufreq C infrastructure.
1249     /// - The pointer arguments must be valid pointers.
fast_switch_callback( ptr: *mut bindings::cpufreq_policy, target_freq: u32, ) -> kernel::ffi::c_uint1250     unsafe extern "C" fn fast_switch_callback(
1251         ptr: *mut bindings::cpufreq_policy,
1252         target_freq: u32,
1253     ) -> kernel::ffi::c_uint {
1254         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1255         // lifetime of `policy`.
1256         let policy = unsafe { Policy::from_raw_mut(ptr) };
1257         T::fast_switch(policy, target_freq)
1258     }
1259 
1260     /// Driver's `adjust_perf` callback.
1261     ///
1262     /// # Safety
1263     ///
1264     /// - This function may only be called from the cpufreq C infrastructure.
adjust_perf_callback( cpu: u32, min_perf: usize, target_perf: usize, capacity: usize, )1265     unsafe extern "C" fn adjust_perf_callback(
1266         cpu: u32,
1267         min_perf: usize,
1268         target_perf: usize,
1269         capacity: usize,
1270     ) {
1271         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1272         let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
1273 
1274         if let Ok(mut policy) = PolicyCpu::from_cpu(cpu_id) {
1275             T::adjust_perf(&mut policy, min_perf, target_perf, capacity);
1276         }
1277     }
1278 
1279     /// Driver's `get_intermediate` 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.
get_intermediate_callback( ptr: *mut bindings::cpufreq_policy, index: u32, ) -> kernel::ffi::c_uint1285     unsafe extern "C" fn get_intermediate_callback(
1286         ptr: *mut bindings::cpufreq_policy,
1287         index: u32,
1288     ) -> kernel::ffi::c_uint {
1289         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1290         // lifetime of `policy`.
1291         let policy = unsafe { Policy::from_raw_mut(ptr) };
1292 
1293         // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1294         // frequency table.
1295         let index = unsafe { TableIndex::new(index as usize) };
1296 
1297         T::get_intermediate(policy, index)
1298     }
1299 
1300     /// Driver's `target_intermediate` callback.
1301     ///
1302     /// # Safety
1303     ///
1304     /// - This function may only be called from the cpufreq C infrastructure.
1305     /// - The pointer arguments must be valid pointers.
target_intermediate_callback( ptr: *mut bindings::cpufreq_policy, index: u32, ) -> kernel::ffi::c_int1306     unsafe extern "C" fn target_intermediate_callback(
1307         ptr: *mut bindings::cpufreq_policy,
1308         index: u32,
1309     ) -> kernel::ffi::c_int {
1310         from_result(|| {
1311             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1312             // lifetime of `policy`.
1313             let policy = unsafe { Policy::from_raw_mut(ptr) };
1314 
1315             // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the
1316             // frequency table.
1317             let index = unsafe { TableIndex::new(index as usize) };
1318 
1319             T::target_intermediate(policy, index).map(|()| 0)
1320         })
1321     }
1322 
1323     /// Driver's `get` callback.
1324     ///
1325     /// # Safety
1326     ///
1327     /// - This function may only be called from the cpufreq C infrastructure.
get_callback(cpu: u32) -> kernel::ffi::c_uint1328     unsafe extern "C" fn get_callback(cpu: u32) -> kernel::ffi::c_uint {
1329         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1330         let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
1331 
1332         PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
1333     }
1334 
1335     /// Driver's `update_limit` callback.
1336     ///
1337     /// # Safety
1338     ///
1339     /// - This function may only be called from the cpufreq C infrastructure.
1340     /// - The pointer arguments must be valid pointers.
update_limits_callback(ptr: *mut bindings::cpufreq_policy)1341     unsafe extern "C" fn update_limits_callback(ptr: *mut bindings::cpufreq_policy) {
1342         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1343         // lifetime of `policy`.
1344         let policy = unsafe { Policy::from_raw_mut(ptr) };
1345         T::update_limits(policy);
1346     }
1347 
1348     /// Driver's `bios_limit` callback.
1349     ///
1350     /// # Safety
1351     ///
1352     /// - This function may only be called from the cpufreq C infrastructure.
1353     /// - The pointer arguments must be valid pointers.
bios_limit_callback(cpu: i32, limit: *mut u32) -> kernel::ffi::c_int1354     unsafe extern "C" fn bios_limit_callback(cpu: i32, limit: *mut u32) -> kernel::ffi::c_int {
1355         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
1356         let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) };
1357 
1358         from_result(|| {
1359             let mut policy = PolicyCpu::from_cpu(cpu_id)?;
1360 
1361             // SAFETY: `limit` is guaranteed by the C code to be valid.
1362             T::bios_limit(&mut policy, &mut (unsafe { *limit })).map(|()| 0)
1363         })
1364     }
1365 
1366     /// Driver's `set_boost` callback.
1367     ///
1368     /// # Safety
1369     ///
1370     /// - This function may only be called from the cpufreq C infrastructure.
1371     /// - The pointer arguments must be valid pointers.
set_boost_callback( ptr: *mut bindings::cpufreq_policy, state: i32, ) -> kernel::ffi::c_int1372     unsafe extern "C" fn set_boost_callback(
1373         ptr: *mut bindings::cpufreq_policy,
1374         state: i32,
1375     ) -> kernel::ffi::c_int {
1376         from_result(|| {
1377             // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1378             // lifetime of `policy`.
1379             let policy = unsafe { Policy::from_raw_mut(ptr) };
1380             T::set_boost(policy, state).map(|()| 0)
1381         })
1382     }
1383 
1384     /// Driver's `register_em` callback.
1385     ///
1386     /// # Safety
1387     ///
1388     /// - This function may only be called from the cpufreq C infrastructure.
1389     /// - The pointer arguments must be valid pointers.
register_em_callback(ptr: *mut bindings::cpufreq_policy)1390     unsafe extern "C" fn register_em_callback(ptr: *mut bindings::cpufreq_policy) {
1391         // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1392         // lifetime of `policy`.
1393         let policy = unsafe { Policy::from_raw_mut(ptr) };
1394         T::register_em(policy);
1395     }
1396 }
1397 
1398 impl<T: Driver> Drop for Registration<T> {
1399     /// Unregisters with the cpufreq core.
drop(&mut self)1400     fn drop(&mut self) {
1401         // SAFETY: `self.0` is guaranteed to be valid for the lifetime of `Registration`.
1402         unsafe { bindings::cpufreq_unregister_driver(self.0.get_mut()) };
1403     }
1404 }
1405