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