kernel/cpufreq.rs
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
11use 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)]
25use crate::clk::Clk;
26
27use core::{
28 cell::UnsafeCell,
29 marker::PhantomData,
30 mem::MaybeUninit,
31 ops::{Deref, DerefMut},
32 pin::Pin,
33 ptr,
34};
35
36use macros::vtable;
37
38/// Maximum length of CPU frequency driver's name.
39const CPUFREQ_NAME_LEN: usize = bindings::CPUFREQ_NAME_LEN as usize;
40
41/// Default transition latency value in nanoseconds.
42pub const ETERNAL_LATENCY_NS: u32 = bindings::CPUFREQ_ETERNAL as u32;
43
44/// CPU frequency driver flags.
45pub 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.
69const CPUFREQ_RELATION_L: u32 = 0;
70const CPUFREQ_RELATION_H: u32 = 1;
71const CPUFREQ_RELATION_C: u32 = 2;
72
73/// Can be used with any of the above values.
74const 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)]
80pub 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
89impl Relation {
90 // Construct from a C-compatible `u32` value.
91 fn new(val: u32) -> Result<Self> {
92 let efficient = val & CPUFREQ_RELATION_E != 0;
93
94 Ok(match val & !CPUFREQ_RELATION_E {
95 CPUFREQ_RELATION_L => Self::Low(efficient),
96 CPUFREQ_RELATION_H => Self::High(efficient),
97 CPUFREQ_RELATION_C => Self::Close(efficient),
98 _ => return Err(EINVAL),
99 })
100 }
101}
102
103impl From<Relation> for u32 {
104 // Convert to a C-compatible `u32` value.
105 fn from(rel: Relation) -> Self {
106 let (mut val, efficient) = match rel {
107 Relation::Low(e) => (CPUFREQ_RELATION_L, e),
108 Relation::High(e) => (CPUFREQ_RELATION_H, e),
109 Relation::Close(e) => (CPUFREQ_RELATION_C, e),
110 };
111
112 if efficient {
113 val |= CPUFREQ_RELATION_E;
114 }
115
116 val
117 }
118}
119
120/// Policy data.
121///
122/// Rust abstraction for the C `struct cpufreq_policy_data`.
123///
124/// # Invariants
125///
126/// A [`PolicyData`] instance always corresponds to a valid C `struct cpufreq_policy_data`.
127///
128/// The callers must ensure that the `struct cpufreq_policy_data` is valid for access and remains
129/// valid for the lifetime of the returned reference.
130#[repr(transparent)]
131pub struct PolicyData(Opaque<bindings::cpufreq_policy_data>);
132
133impl PolicyData {
134 /// Creates a mutable reference to an existing `struct cpufreq_policy_data` pointer.
135 ///
136 /// # Safety
137 ///
138 /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime
139 /// of the returned reference.
140 #[inline]
141 pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy_data) -> &'a mut Self {
142 // SAFETY: Guaranteed by the safety requirements of the function.
143 //
144 // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the
145 // lifetime of the returned reference.
146 unsafe { &mut *ptr.cast() }
147 }
148
149 /// Returns a raw pointer to the underlying C `cpufreq_policy_data`.
150 #[inline]
151 pub fn as_raw(&self) -> *mut bindings::cpufreq_policy_data {
152 let this: *const Self = self;
153 this.cast_mut().cast()
154 }
155
156 /// Wrapper for `cpufreq_generic_frequency_table_verify`.
157 #[inline]
158 pub fn generic_verify(&self) -> Result {
159 // SAFETY: By the type invariant, the pointer stored in `self` is valid.
160 to_result(unsafe { bindings::cpufreq_generic_frequency_table_verify(self.as_raw()) })
161 }
162}
163
164/// The frequency table index.
165///
166/// Represents index with a frequency table.
167///
168/// # Invariants
169///
170/// The index must correspond to a valid entry in the [`Table`] it is used for.
171#[derive(Copy, Clone, PartialEq, Eq, Debug)]
172pub struct TableIndex(usize);
173
174impl TableIndex {
175 /// Creates an instance of [`TableIndex`].
176 ///
177 /// # Safety
178 ///
179 /// The caller must ensure that `index` correspond to a valid entry in the [`Table`] it is used
180 /// for.
181 pub unsafe fn new(index: usize) -> Self {
182 // INVARIANT: The caller ensures that `index` correspond to a valid entry in the [`Table`].
183 Self(index)
184 }
185}
186
187impl From<TableIndex> for usize {
188 #[inline]
189 fn from(index: TableIndex) -> Self {
190 index.0
191 }
192}
193
194/// CPU frequency table.
195///
196/// Rust abstraction for the C `struct cpufreq_frequency_table`.
197///
198/// # Invariants
199///
200/// A [`Table`] instance always corresponds to a valid C `struct cpufreq_frequency_table`.
201///
202/// The callers must ensure that the `struct cpufreq_frequency_table` is valid for access and
203/// remains valid for the lifetime of the returned reference.
204///
205/// ## Examples
206///
207/// The following example demonstrates how to read a frequency value from [`Table`].
208///
209/// ```
210/// use kernel::cpufreq::{Policy, TableIndex};
211///
212/// fn show_freq(policy: &Policy) -> Result {
213/// let table = policy.freq_table()?;
214///
215/// // SAFETY: Index is a valid entry in the table.
216/// let index = unsafe { TableIndex::new(0) };
217///
218/// pr_info!("The frequency at index 0 is: {:?}\n", table.freq(index)?);
219/// pr_info!("The flags at index 0 is: {}\n", table.flags(index));
220/// pr_info!("The data at index 0 is: {}\n", table.data(index));
221/// Ok(())
222/// }
223/// ```
224#[repr(transparent)]
225pub struct Table(Opaque<bindings::cpufreq_frequency_table>);
226
227impl Table {
228 /// Creates a reference to an existing C `struct cpufreq_frequency_table` pointer.
229 ///
230 /// # Safety
231 ///
232 /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime
233 /// of the returned reference.
234 #[inline]
235 pub unsafe fn from_raw<'a>(ptr: *const bindings::cpufreq_frequency_table) -> &'a Self {
236 // SAFETY: Guaranteed by the safety requirements of the function.
237 //
238 // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the
239 // lifetime of the returned reference.
240 unsafe { &*ptr.cast() }
241 }
242
243 /// Returns the raw mutable pointer to the C `struct cpufreq_frequency_table`.
244 #[inline]
245 pub fn as_raw(&self) -> *mut bindings::cpufreq_frequency_table {
246 let this: *const Self = self;
247 this.cast_mut().cast()
248 }
249
250 /// Returns frequency at `index` in the [`Table`].
251 #[inline]
252 pub fn freq(&self, index: TableIndex) -> Result<Hertz> {
253 // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
254 // guaranteed to be valid by its safety requirements.
255 Ok(Hertz::from_khz(unsafe {
256 (*self.as_raw().add(index.into())).frequency.try_into()?
257 }))
258 }
259
260 /// Returns flags at `index` in the [`Table`].
261 #[inline]
262 pub fn flags(&self, index: TableIndex) -> u32 {
263 // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
264 // guaranteed to be valid by its safety requirements.
265 unsafe { (*self.as_raw().add(index.into())).flags }
266 }
267
268 /// Returns data at `index` in the [`Table`].
269 #[inline]
270 pub fn data(&self, index: TableIndex) -> u32 {
271 // SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is
272 // guaranteed to be valid by its safety requirements.
273 unsafe { (*self.as_raw().add(index.into())).driver_data }
274 }
275}
276
277/// CPU frequency table owned and pinned in memory, created from a [`TableBuilder`].
278pub struct TableBox {
279 entries: Pin<KVec<bindings::cpufreq_frequency_table>>,
280}
281
282impl TableBox {
283 /// Constructs a new [`TableBox`] from a [`KVec`] of entries.
284 ///
285 /// # Errors
286 ///
287 /// Returns `EINVAL` if the entries list is empty.
288 #[inline]
289 fn new(entries: KVec<bindings::cpufreq_frequency_table>) -> Result<Self> {
290 if entries.is_empty() {
291 return Err(EINVAL);
292 }
293
294 Ok(Self {
295 // Pin the entries to memory, since we are passing its pointer to the C code.
296 entries: Pin::new(entries),
297 })
298 }
299
300 /// Returns a raw pointer to the underlying C `cpufreq_frequency_table`.
301 #[inline]
302 fn as_raw(&self) -> *const bindings::cpufreq_frequency_table {
303 // The pointer is valid until the table gets dropped.
304 self.entries.as_ptr()
305 }
306}
307
308impl Deref for TableBox {
309 type Target = Table;
310
311 fn deref(&self) -> &Self::Target {
312 // SAFETY: The caller owns TableBox, it is safe to deref.
313 unsafe { Self::Target::from_raw(self.as_raw()) }
314 }
315}
316
317/// CPU frequency table builder.
318///
319/// This is used by the CPU frequency drivers to build a frequency table dynamically.
320///
321/// ## Examples
322///
323/// The following example demonstrates how to create a CPU frequency table.
324///
325/// ```
326/// use kernel::cpufreq::{TableBuilder, TableIndex};
327/// use kernel::clk::Hertz;
328///
329/// let mut builder = TableBuilder::new();
330///
331/// // Adds few entries to the table.
332/// builder.add(Hertz::from_mhz(700), 0, 1).unwrap();
333/// builder.add(Hertz::from_mhz(800), 2, 3).unwrap();
334/// builder.add(Hertz::from_mhz(900), 4, 5).unwrap();
335/// builder.add(Hertz::from_ghz(1), 6, 7).unwrap();
336///
337/// let table = builder.to_table().unwrap();
338///
339/// // SAFETY: Index values correspond to valid entries in the table.
340/// let (index0, index2) = unsafe { (TableIndex::new(0), TableIndex::new(2)) };
341///
342/// assert_eq!(table.freq(index0), Ok(Hertz::from_mhz(700)));
343/// assert_eq!(table.flags(index0), 0);
344/// assert_eq!(table.data(index0), 1);
345///
346/// assert_eq!(table.freq(index2), Ok(Hertz::from_mhz(900)));
347/// assert_eq!(table.flags(index2), 4);
348/// assert_eq!(table.data(index2), 5);
349/// ```
350#[derive(Default)]
351#[repr(transparent)]
352pub struct TableBuilder {
353 entries: KVec<bindings::cpufreq_frequency_table>,
354}
355
356impl TableBuilder {
357 /// Creates a new instance of [`TableBuilder`].
358 #[inline]
359 pub fn new() -> Self {
360 Self {
361 entries: KVec::new(),
362 }
363 }
364
365 /// Adds a new entry to the table.
366 pub fn add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result {
367 // Adds the new entry at the end of the vector.
368 Ok(self.entries.push(
369 bindings::cpufreq_frequency_table {
370 flags,
371 driver_data,
372 frequency: freq.as_khz() as u32,
373 },
374 GFP_KERNEL,
375 )?)
376 }
377
378 /// Consumes the [`TableBuilder`] and returns [`TableBox`].
379 pub fn to_table(mut self) -> Result<TableBox> {
380 // Add last entry to the table.
381 self.add(Hertz(c_ulong::MAX), 0, 0)?;
382
383 TableBox::new(self.entries)
384 }
385}
386
387/// CPU frequency policy.
388///
389/// Rust abstraction for the C `struct cpufreq_policy`.
390///
391/// # Invariants
392///
393/// A [`Policy`] instance always corresponds to a valid C `struct cpufreq_policy`.
394///
395/// The callers must ensure that the `struct cpufreq_policy` is valid for access and remains valid
396/// for the lifetime of the returned reference.
397///
398/// ## Examples
399///
400/// The following example demonstrates how to create a CPU frequency table.
401///
402/// ```
403/// use kernel::cpufreq::{ETERNAL_LATENCY_NS, Policy};
404///
405/// fn update_policy(policy: &mut Policy) {
406/// policy
407/// .set_dvfs_possible_from_any_cpu(true)
408/// .set_fast_switch_possible(true)
409/// .set_transition_latency_ns(ETERNAL_LATENCY_NS);
410///
411/// pr_info!("The policy details are: {:?}\n", (policy.cpu(), policy.cur()));
412/// }
413/// ```
414#[repr(transparent)]
415pub struct Policy(Opaque<bindings::cpufreq_policy>);
416
417impl Policy {
418 /// Creates a reference to an existing `struct cpufreq_policy` pointer.
419 ///
420 /// # Safety
421 ///
422 /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime
423 /// of the returned reference.
424 #[inline]
425 pub unsafe fn from_raw<'a>(ptr: *const bindings::cpufreq_policy) -> &'a Self {
426 // SAFETY: Guaranteed by the safety requirements of the function.
427 //
428 // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the
429 // lifetime of the returned reference.
430 unsafe { &*ptr.cast() }
431 }
432
433 /// Creates a mutable reference to an existing `struct cpufreq_policy` pointer.
434 ///
435 /// # Safety
436 ///
437 /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime
438 /// of the returned reference.
439 #[inline]
440 pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy) -> &'a mut Self {
441 // SAFETY: Guaranteed by the safety requirements of the function.
442 //
443 // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the
444 // lifetime of the returned reference.
445 unsafe { &mut *ptr.cast() }
446 }
447
448 /// Returns a raw mutable pointer to the C `struct cpufreq_policy`.
449 #[inline]
450 fn as_raw(&self) -> *mut bindings::cpufreq_policy {
451 let this: *const Self = self;
452 this.cast_mut().cast()
453 }
454
455 #[inline]
456 fn as_ref(&self) -> &bindings::cpufreq_policy {
457 // SAFETY: By the type invariant, the pointer stored in `self` is valid.
458 unsafe { &*self.as_raw() }
459 }
460
461 #[inline]
462 fn as_mut_ref(&mut self) -> &mut bindings::cpufreq_policy {
463 // SAFETY: By the type invariant, the pointer stored in `self` is valid.
464 unsafe { &mut *self.as_raw() }
465 }
466
467 /// Returns the primary CPU for the [`Policy`].
468 #[inline]
469 pub fn cpu(&self) -> CpuId {
470 // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
471 unsafe { CpuId::from_u32_unchecked(self.as_ref().cpu) }
472 }
473
474 /// Returns the minimum frequency for the [`Policy`].
475 #[inline]
476 pub fn min(&self) -> Hertz {
477 Hertz::from_khz(self.as_ref().min as usize)
478 }
479
480 /// Set the minimum frequency for the [`Policy`].
481 #[inline]
482 pub fn set_min(&mut self, min: Hertz) -> &mut Self {
483 self.as_mut_ref().min = min.as_khz() as u32;
484 self
485 }
486
487 /// Returns the maximum frequency for the [`Policy`].
488 #[inline]
489 pub fn max(&self) -> Hertz {
490 Hertz::from_khz(self.as_ref().max as usize)
491 }
492
493 /// Set the maximum frequency for the [`Policy`].
494 #[inline]
495 pub fn set_max(&mut self, max: Hertz) -> &mut Self {
496 self.as_mut_ref().max = max.as_khz() as u32;
497 self
498 }
499
500 /// Returns the current frequency for the [`Policy`].
501 #[inline]
502 pub fn cur(&self) -> Hertz {
503 Hertz::from_khz(self.as_ref().cur as usize)
504 }
505
506 /// Returns the suspend frequency for the [`Policy`].
507 #[inline]
508 pub fn suspend_freq(&self) -> Hertz {
509 Hertz::from_khz(self.as_ref().suspend_freq as usize)
510 }
511
512 /// Sets the suspend frequency for the [`Policy`].
513 #[inline]
514 pub fn set_suspend_freq(&mut self, freq: Hertz) -> &mut Self {
515 self.as_mut_ref().suspend_freq = freq.as_khz() as u32;
516 self
517 }
518
519 /// Provides a wrapper to the generic suspend routine.
520 #[inline]
521 pub fn generic_suspend(&mut self) -> Result {
522 // SAFETY: By the type invariant, the pointer stored in `self` is valid.
523 to_result(unsafe { bindings::cpufreq_generic_suspend(self.as_mut_ref()) })
524 }
525
526 /// Provides a wrapper to the generic get routine.
527 #[inline]
528 pub fn generic_get(&self) -> Result<u32> {
529 // SAFETY: By the type invariant, the pointer stored in `self` is valid.
530 Ok(unsafe { bindings::cpufreq_generic_get(self.cpu().into()) })
531 }
532
533 /// Provides a wrapper to the register with energy model using the OPP core.
534 #[cfg(CONFIG_PM_OPP)]
535 #[inline]
536 pub fn register_em_opp(&mut self) {
537 // SAFETY: By the type invariant, the pointer stored in `self` is valid.
538 unsafe { bindings::cpufreq_register_em_with_opp(self.as_mut_ref()) };
539 }
540
541 /// Gets [`cpumask::Cpumask`] for a cpufreq [`Policy`].
542 #[inline]
543 pub fn cpus(&mut self) -> &mut cpumask::Cpumask {
544 // SAFETY: The pointer to `cpus` is valid for writing and remains valid for the lifetime of
545 // the returned reference.
546 unsafe { cpumask::CpumaskVar::as_mut_ref(&mut self.as_mut_ref().cpus) }
547 }
548
549 /// Sets clock for the [`Policy`].
550 ///
551 /// # Safety
552 ///
553 /// The caller must guarantee that the returned [`Clk`] is not dropped while it is getting used
554 /// by the C code.
555 #[cfg(CONFIG_COMMON_CLK)]
556 pub unsafe fn set_clk(&mut self, dev: &Device, name: Option<&CStr>) -> Result<Clk> {
557 let clk = Clk::get(dev, name)?;
558 self.as_mut_ref().clk = clk.as_raw();
559 Ok(clk)
560 }
561
562 /// Allows / disallows frequency switching code to run on any CPU.
563 #[inline]
564 pub fn set_dvfs_possible_from_any_cpu(&mut self, val: bool) -> &mut Self {
565 self.as_mut_ref().dvfs_possible_from_any_cpu = val;
566 self
567 }
568
569 /// Returns if fast switching of frequencies is possible or not.
570 #[inline]
571 pub fn fast_switch_possible(&self) -> bool {
572 self.as_ref().fast_switch_possible
573 }
574
575 /// Enables / disables fast frequency switching.
576 #[inline]
577 pub fn set_fast_switch_possible(&mut self, val: bool) -> &mut Self {
578 self.as_mut_ref().fast_switch_possible = val;
579 self
580 }
581
582 /// Sets transition latency (in nanoseconds) for the [`Policy`].
583 #[inline]
584 pub fn set_transition_latency_ns(&mut self, latency_ns: u32) -> &mut Self {
585 self.as_mut_ref().cpuinfo.transition_latency = latency_ns;
586 self
587 }
588
589 /// Sets cpuinfo `min_freq`.
590 #[inline]
591 pub fn set_cpuinfo_min_freq(&mut self, min_freq: Hertz) -> &mut Self {
592 self.as_mut_ref().cpuinfo.min_freq = min_freq.as_khz() as u32;
593 self
594 }
595
596 /// Sets cpuinfo `max_freq`.
597 #[inline]
598 pub fn set_cpuinfo_max_freq(&mut self, max_freq: Hertz) -> &mut Self {
599 self.as_mut_ref().cpuinfo.max_freq = max_freq.as_khz() as u32;
600 self
601 }
602
603 /// Set `transition_delay_us`, i.e. the minimum time between successive frequency change
604 /// requests.
605 #[inline]
606 pub fn set_transition_delay_us(&mut self, transition_delay_us: u32) -> &mut Self {
607 self.as_mut_ref().transition_delay_us = transition_delay_us;
608 self
609 }
610
611 /// Returns reference to the CPU frequency [`Table`] for the [`Policy`].
612 pub fn freq_table(&self) -> Result<&Table> {
613 if self.as_ref().freq_table.is_null() {
614 return Err(EINVAL);
615 }
616
617 // SAFETY: The `freq_table` is guaranteed to be valid for reading and remains valid for the
618 // lifetime of the returned reference.
619 Ok(unsafe { Table::from_raw(self.as_ref().freq_table) })
620 }
621
622 /// Sets the CPU frequency [`Table`] for the [`Policy`].
623 ///
624 /// # Safety
625 ///
626 /// The caller must guarantee that the [`Table`] is not dropped while it is getting used by the
627 /// C code.
628 #[inline]
629 pub unsafe fn set_freq_table(&mut self, table: &Table) -> &mut Self {
630 self.as_mut_ref().freq_table = table.as_raw();
631 self
632 }
633
634 /// Returns the [`Policy`]'s private data.
635 pub fn data<T: ForeignOwnable>(&mut self) -> Option<<T>::Borrowed<'_>> {
636 if self.as_ref().driver_data.is_null() {
637 None
638 } else {
639 // SAFETY: The data is earlier set from [`set_data`].
640 Some(unsafe { T::borrow(self.as_ref().driver_data.cast()) })
641 }
642 }
643
644 /// Sets the private data of the [`Policy`] using a foreign-ownable wrapper.
645 ///
646 /// # Errors
647 ///
648 /// Returns `EBUSY` if private data is already set.
649 fn set_data<T: ForeignOwnable>(&mut self, data: T) -> Result {
650 if self.as_ref().driver_data.is_null() {
651 // Transfer the ownership of the data to the foreign interface.
652 self.as_mut_ref().driver_data = <T as ForeignOwnable>::into_foreign(data) as _;
653 Ok(())
654 } else {
655 Err(EBUSY)
656 }
657 }
658
659 /// Clears and returns ownership of the private data.
660 fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> {
661 if self.as_ref().driver_data.is_null() {
662 None
663 } else {
664 let data = Some(
665 // SAFETY: The data is earlier set by us from [`set_data`]. It is safe to take
666 // back the ownership of the data from the foreign interface.
667 unsafe { <T as ForeignOwnable>::from_foreign(self.as_ref().driver_data.cast()) },
668 );
669 self.as_mut_ref().driver_data = ptr::null_mut();
670 data
671 }
672 }
673}
674
675/// CPU frequency policy created from a CPU number.
676///
677/// This struct represents the CPU frequency policy obtained for a specific CPU, providing safe
678/// access to the underlying `cpufreq_policy` and ensuring proper cleanup when the `PolicyCpu` is
679/// dropped.
680struct PolicyCpu<'a>(&'a mut Policy);
681
682impl<'a> PolicyCpu<'a> {
683 fn from_cpu(cpu: CpuId) -> Result<Self> {
684 // SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU.
685 let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(cpu.into()) })?;
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
695impl<'a> Deref for PolicyCpu<'a> {
696 type Target = Policy;
697
698 fn deref(&self) -> &Self::Target {
699 self.0
700 }
701}
702
703impl<'a> DerefMut for PolicyCpu<'a> {
704 fn deref_mut(&mut self) -> &mut Policy {
705 self.0
706 }
707}
708
709impl<'a> Drop for PolicyCpu<'a> {
710 fn drop(&mut self) {
711 // SAFETY: The underlying pointer is guaranteed to be valid for the lifetime of `self`.
712 unsafe { bindings::cpufreq_cpu_put(self.0.as_raw()) };
713 }
714}
715
716/// CPU frequency driver.
717///
718/// Implement this trait to provide a CPU frequency driver and its callbacks.
719///
720/// Reference: <https://docs.kernel.org/cpu-freq/cpu-drivers.html>
721#[vtable]
722pub trait Driver {
723 /// Driver's name.
724 const NAME: &'static CStr;
725
726 /// Driver's flags.
727 const FLAGS: u16;
728
729 /// Boost support.
730 const BOOST_ENABLED: bool;
731
732 /// Policy specific data.
733 ///
734 /// Require that `PData` implements `ForeignOwnable`. We guarantee to never move the underlying
735 /// wrapped data structure.
736 type PData: ForeignOwnable;
737
738 /// Driver's `init` callback.
739 fn init(policy: &mut Policy) -> Result<Self::PData>;
740
741 /// Driver's `exit` callback.
742 fn exit(_policy: &mut Policy, _data: Option<Self::PData>) -> Result {
743 build_error!(VTABLE_DEFAULT_ERROR)
744 }
745
746 /// Driver's `online` callback.
747 fn online(_policy: &mut Policy) -> Result {
748 build_error!(VTABLE_DEFAULT_ERROR)
749 }
750
751 /// Driver's `offline` callback.
752 fn offline(_policy: &mut Policy) -> Result {
753 build_error!(VTABLE_DEFAULT_ERROR)
754 }
755
756 /// Driver's `suspend` callback.
757 fn suspend(_policy: &mut Policy) -> Result {
758 build_error!(VTABLE_DEFAULT_ERROR)
759 }
760
761 /// Driver's `resume` callback.
762 fn resume(_policy: &mut Policy) -> Result {
763 build_error!(VTABLE_DEFAULT_ERROR)
764 }
765
766 /// Driver's `ready` callback.
767 fn ready(_policy: &mut Policy) {
768 build_error!(VTABLE_DEFAULT_ERROR)
769 }
770
771 /// Driver's `verify` callback.
772 fn verify(data: &mut PolicyData) -> Result;
773
774 /// Driver's `setpolicy` callback.
775 fn setpolicy(_policy: &mut Policy) -> Result {
776 build_error!(VTABLE_DEFAULT_ERROR)
777 }
778
779 /// Driver's `target` callback.
780 fn target(_policy: &mut Policy, _target_freq: u32, _relation: Relation) -> Result {
781 build_error!(VTABLE_DEFAULT_ERROR)
782 }
783
784 /// Driver's `target_index` callback.
785 fn target_index(_policy: &mut Policy, _index: TableIndex) -> Result {
786 build_error!(VTABLE_DEFAULT_ERROR)
787 }
788
789 /// Driver's `fast_switch` callback.
790 fn fast_switch(_policy: &mut Policy, _target_freq: u32) -> u32 {
791 build_error!(VTABLE_DEFAULT_ERROR)
792 }
793
794 /// Driver's `adjust_perf` callback.
795 fn adjust_perf(_policy: &mut Policy, _min_perf: usize, _target_perf: usize, _capacity: usize) {
796 build_error!(VTABLE_DEFAULT_ERROR)
797 }
798
799 /// Driver's `get_intermediate` callback.
800 fn get_intermediate(_policy: &mut Policy, _index: TableIndex) -> u32 {
801 build_error!(VTABLE_DEFAULT_ERROR)
802 }
803
804 /// Driver's `target_intermediate` callback.
805 fn target_intermediate(_policy: &mut Policy, _index: TableIndex) -> Result {
806 build_error!(VTABLE_DEFAULT_ERROR)
807 }
808
809 /// Driver's `get` callback.
810 fn get(_policy: &mut Policy) -> Result<u32> {
811 build_error!(VTABLE_DEFAULT_ERROR)
812 }
813
814 /// Driver's `update_limits` callback.
815 fn update_limits(_policy: &mut Policy) {
816 build_error!(VTABLE_DEFAULT_ERROR)
817 }
818
819 /// Driver's `bios_limit` callback.
820 fn bios_limit(_policy: &mut Policy, _limit: &mut u32) -> Result {
821 build_error!(VTABLE_DEFAULT_ERROR)
822 }
823
824 /// Driver's `set_boost` callback.
825 fn set_boost(_policy: &mut Policy, _state: i32) -> Result {
826 build_error!(VTABLE_DEFAULT_ERROR)
827 }
828
829 /// Driver's `register_em` callback.
830 fn register_em(_policy: &mut Policy) {
831 build_error!(VTABLE_DEFAULT_ERROR)
832 }
833}
834
835/// CPU frequency driver Registration.
836///
837/// ## Examples
838///
839/// The following example demonstrates how to register a cpufreq driver.
840///
841/// ```
842/// use kernel::{
843/// cpufreq,
844/// c_str,
845/// device::{Core, Device},
846/// macros::vtable,
847/// of, platform,
848/// sync::Arc,
849/// };
850/// struct SampleDevice;
851///
852/// #[derive(Default)]
853/// struct SampleDriver;
854///
855/// #[vtable]
856/// impl cpufreq::Driver for SampleDriver {
857/// const NAME: &'static CStr = c_str!("cpufreq-sample");
858/// const FLAGS: u16 = cpufreq::flags::NEED_INITIAL_FREQ_CHECK | cpufreq::flags::IS_COOLING_DEV;
859/// const BOOST_ENABLED: bool = true;
860///
861/// type PData = Arc<SampleDevice>;
862///
863/// fn init(policy: &mut cpufreq::Policy) -> Result<Self::PData> {
864/// // Initialize here
865/// Ok(Arc::new(SampleDevice, GFP_KERNEL)?)
866/// }
867///
868/// fn exit(_policy: &mut cpufreq::Policy, _data: Option<Self::PData>) -> Result {
869/// Ok(())
870/// }
871///
872/// fn suspend(policy: &mut cpufreq::Policy) -> Result {
873/// policy.generic_suspend()
874/// }
875///
876/// fn verify(data: &mut cpufreq::PolicyData) -> Result {
877/// data.generic_verify()
878/// }
879///
880/// fn target_index(policy: &mut cpufreq::Policy, index: cpufreq::TableIndex) -> Result {
881/// // Update CPU frequency
882/// Ok(())
883/// }
884///
885/// fn get(policy: &mut cpufreq::Policy) -> Result<u32> {
886/// policy.generic_get()
887/// }
888/// }
889///
890/// impl platform::Driver for SampleDriver {
891/// type IdInfo = ();
892/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
893///
894/// fn probe(
895/// pdev: &platform::Device<Core>,
896/// _id_info: Option<&Self::IdInfo>,
897/// ) -> Result<Pin<KBox<Self>>> {
898/// cpufreq::Registration::<SampleDriver>::new_foreign_owned(pdev.as_ref())?;
899/// Ok(KBox::new(Self {}, GFP_KERNEL)?.into())
900/// }
901/// }
902/// ```
903#[repr(transparent)]
904pub 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.
908unsafe 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.
913unsafe impl<T: Driver> Send for Registration<T> {}
914
915impl<T: Driver> Registration<T> {
916 const VTABLE: bindings::cpufreq_driver = bindings::cpufreq_driver {
917 name: Self::copy_name(T::NAME),
918 boost_enabled: T::BOOST_ENABLED,
919 flags: T::FLAGS,
920
921 // Initialize mandatory callbacks.
922 init: Some(Self::init_callback),
923 verify: Some(Self::verify_callback),
924
925 // Initialize optional callbacks based on the traits of `T`.
926 setpolicy: if T::HAS_SETPOLICY {
927 Some(Self::setpolicy_callback)
928 } else {
929 None
930 },
931 target: if T::HAS_TARGET {
932 Some(Self::target_callback)
933 } else {
934 None
935 },
936 target_index: if T::HAS_TARGET_INDEX {
937 Some(Self::target_index_callback)
938 } else {
939 None
940 },
941 fast_switch: if T::HAS_FAST_SWITCH {
942 Some(Self::fast_switch_callback)
943 } else {
944 None
945 },
946 adjust_perf: if T::HAS_ADJUST_PERF {
947 Some(Self::adjust_perf_callback)
948 } else {
949 None
950 },
951 get_intermediate: if T::HAS_GET_INTERMEDIATE {
952 Some(Self::get_intermediate_callback)
953 } else {
954 None
955 },
956 target_intermediate: if T::HAS_TARGET_INTERMEDIATE {
957 Some(Self::target_intermediate_callback)
958 } else {
959 None
960 },
961 get: if T::HAS_GET {
962 Some(Self::get_callback)
963 } else {
964 None
965 },
966 update_limits: if T::HAS_UPDATE_LIMITS {
967 Some(Self::update_limits_callback)
968 } else {
969 None
970 },
971 bios_limit: if T::HAS_BIOS_LIMIT {
972 Some(Self::bios_limit_callback)
973 } else {
974 None
975 },
976 online: if T::HAS_ONLINE {
977 Some(Self::online_callback)
978 } else {
979 None
980 },
981 offline: if T::HAS_OFFLINE {
982 Some(Self::offline_callback)
983 } else {
984 None
985 },
986 exit: if T::HAS_EXIT {
987 Some(Self::exit_callback)
988 } else {
989 None
990 },
991 suspend: if T::HAS_SUSPEND {
992 Some(Self::suspend_callback)
993 } else {
994 None
995 },
996 resume: if T::HAS_RESUME {
997 Some(Self::resume_callback)
998 } else {
999 None
1000 },
1001 ready: if T::HAS_READY {
1002 Some(Self::ready_callback)
1003 } else {
1004 None
1005 },
1006 set_boost: if T::HAS_SET_BOOST {
1007 Some(Self::set_boost_callback)
1008 } else {
1009 None
1010 },
1011 register_em: if T::HAS_REGISTER_EM {
1012 Some(Self::register_em_callback)
1013 } else {
1014 None
1015 },
1016 // SAFETY: All zeros is a valid value for `bindings::cpufreq_driver`.
1017 ..unsafe { MaybeUninit::zeroed().assume_init() }
1018 };
1019
1020 const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] {
1021 let src = name.as_bytes_with_nul();
1022 let mut dst = [0; CPUFREQ_NAME_LEN];
1023
1024 build_assert!(src.len() <= CPUFREQ_NAME_LEN);
1025
1026 let mut i = 0;
1027 while i < src.len() {
1028 dst[i] = src[i];
1029 i += 1;
1030 }
1031
1032 dst
1033 }
1034
1035 /// Registers a CPU frequency driver with the cpufreq core.
1036 pub fn new() -> Result<Self> {
1037 // We can't use `&Self::VTABLE` directly because the cpufreq core modifies some fields in
1038 // the C `struct cpufreq_driver`, which requires a mutable reference.
1039 let mut drv = KBox::new(UnsafeCell::new(Self::VTABLE), GFP_KERNEL)?;
1040
1041 // SAFETY: `drv` is guaranteed to be valid for the lifetime of `Registration`.
1042 to_result(unsafe { bindings::cpufreq_register_driver(drv.get_mut()) })?;
1043
1044 Ok(Self(drv, PhantomData))
1045 }
1046
1047 /// Same as [`Registration::new`], but does not return a [`Registration`] instance.
1048 ///
1049 /// Instead the [`Registration`] is owned by [`Devres`] and will be revoked / dropped, once the
1050 /// device is detached.
1051 pub fn new_foreign_owned(dev: &Device<Bound>) -> Result {
1052 Devres::new_foreign_owned(dev, Self::new()?, GFP_KERNEL)
1053 }
1054}
1055
1056/// CPU frequency driver callbacks.
1057impl<T: Driver> Registration<T> {
1058 /// Driver's `init` callback.
1059 ///
1060 /// # Safety
1061 ///
1062 /// - This function may only be called from the cpufreq C infrastructure.
1063 /// - The pointer arguments must be valid pointers.
1064 unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> 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.
1082 unsafe extern "C" fn exit_callback(ptr: *mut bindings::cpufreq_policy) {
1083 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1084 // lifetime of `policy`.
1085 let policy = unsafe { Policy::from_raw_mut(ptr) };
1086
1087 let data = policy.clear_data();
1088 let _ = T::exit(policy, data);
1089 }
1090
1091 /// Driver's `online` callback.
1092 ///
1093 /// # Safety
1094 ///
1095 /// - This function may only be called from the cpufreq C infrastructure.
1096 /// - The pointer arguments must be valid pointers.
1097 unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> 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.
1112 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.
1129 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.
1146 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.
1161 unsafe extern "C" fn ready_callback(ptr: *mut bindings::cpufreq_policy) {
1162 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
1163 // lifetime of `policy`.
1164 let policy = unsafe { Policy::from_raw_mut(ptr) };
1165 T::ready(policy);
1166 }
1167
1168 /// Driver's `verify` callback.
1169 ///
1170 /// # Safety
1171 ///
1172 /// - This function may only be called from the cpufreq C infrastructure.
1173 /// - The pointer arguments must be valid pointers.
1174 unsafe extern "C" fn verify_callback(
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.
1191 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.
1208 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.
1227 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.
1250 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.
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.
1285 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.
1306 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.
1328 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.
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.
1354 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.
1372 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.
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
1398impl<T: Driver> Drop for Registration<T> {
1399 /// Unregisters with the cpufreq core.
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}