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