File Index
Files and directories
Sign in
FILE

cpufreq.rs

File preview with syntax highlighting.

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