// SPDX-License-Identifier: GPL-2.012//! CPU frequency scaling.3//!4//! This module provides rust abstractions for interacting with the cpufreq subsystem.5//!6//! C header: [`include/linux/cpufreq.h`](srctree/include/linux/cpufreq.h)7//!8//! Reference: <https://docs.kernel.org/admin-guide/pm/cpufreq.html>910use crate::{11clk::Hertz,12cpu::CpuId,13cpumask,14device::{Bound, Device},15devres,16error::{code::*, from_err_ptr, from_result, to_result, Result, VTABLE_DEFAULT_ERROR},17ffi::{c_char, c_ulong},18prelude::*,19types::ForeignOwnable,20types::Opaque,21};2223#[cfg(CONFIG_COMMON_CLK)]24use crate::clk::Clk;2526use core::{27cell::UnsafeCell,28marker::PhantomData,29ops::{Deref, DerefMut},30pin::Pin,31ptr,32};3334use macros::vtable;3536/// Maximum length of CPU frequency driver's name.37const CPUFREQ_NAME_LEN: usize = bindings::CPUFREQ_NAME_LEN as usize;3839/// Default transition latency value in nanoseconds.40pub const ETERNAL_LATENCY_NS: u32 = bindings::CPUFREQ_ETERNAL as u32;4142/// CPU frequency driver flags.43pub mod flags {44/// Driver needs to update internal limits even if frequency remains unchanged.45pub const NEED_UPDATE_LIMITS: u16 = 1 << 0;4647/// Platform where constants like `loops_per_jiffy` are unaffected by frequency changes.48pub const CONST_LOOPS: u16 = 1 << 1;4950/// Register driver as a thermal cooling device automatically.51pub const IS_COOLING_DEV: u16 = 1 << 2;5253/// Supports multiple clock domains with per-policy governors in `cpu/cpuN/cpufreq/`.54pub const HAVE_GOVERNOR_PER_POLICY: u16 = 1 << 3;5556/// Allows post-change notifications outside of the `target()` routine.57pub const ASYNC_NOTIFICATION: u16 = 1 << 4;5859/// Ensure CPU starts at a valid frequency from the driver's freq-table.60pub const NEED_INITIAL_FREQ_CHECK: u16 = 1 << 5;6162/// Disallow governors with `dynamic_switching` capability.63pub const NO_AUTO_DYNAMIC_SWITCHING: u16 = 1 << 6;64}6566/// Relations from the C code.67const CPUFREQ_RELATION_L: u32 = 0;68const CPUFREQ_RELATION_H: u32 = 1;69const CPUFREQ_RELATION_C: u32 = 2;7071/// Can be used with any of the above values.72const CPUFREQ_RELATION_E: u32 = 1 << 2;7374/// CPU frequency selection relations.75///76/// CPU frequency selection relations, each optionally marked as "efficient".77#[derive(Copy, Clone, Debug, Eq, PartialEq)]78pub enum Relation {79/// Select the lowest frequency at or above target.80Low(bool),81/// Select the highest frequency below or at target.82High(bool),83/// Select the closest frequency to the target.84Close(bool),85}8687impl Relation {88// Construct from a C-compatible `u32` value.89fn new(val: u32) -> Result<Self> {90let efficient = val & CPUFREQ_RELATION_E != 0;9192Ok(match val & !CPUFREQ_RELATION_E {93CPUFREQ_RELATION_L => Self::Low(efficient),94CPUFREQ_RELATION_H => Self::High(efficient),95CPUFREQ_RELATION_C => Self::Close(efficient),96_ => return Err(EINVAL),97})98}99}100101impl From<Relation> for u32 {102// Convert to a C-compatible `u32` value.103fn from(rel: Relation) -> Self {104let (mut val, efficient) = match rel {105Relation::Low(e) => (CPUFREQ_RELATION_L, e),106Relation::High(e) => (CPUFREQ_RELATION_H, e),107Relation::Close(e) => (CPUFREQ_RELATION_C, e),108};109110if efficient {111val |= CPUFREQ_RELATION_E;112}113114val115}116}117118/// Policy data.119///120/// Rust abstraction for the C `struct cpufreq_policy_data`.121///122/// # Invariants123///124/// A [`PolicyData`] instance always corresponds to a valid C `struct cpufreq_policy_data`.125///126/// The callers must ensure that the `struct cpufreq_policy_data` is valid for access and remains127/// valid for the lifetime of the returned reference.128#[repr(transparent)]129pub struct PolicyData(Opaque<bindings::cpufreq_policy_data>);130131impl PolicyData {132/// Creates a mutable reference to an existing `struct cpufreq_policy_data` pointer.133///134/// # Safety135///136/// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime137/// of the returned reference.138#[inline]139pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy_data) -> &'a mut Self {140// SAFETY: Guaranteed by the safety requirements of the function.141//142// INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the143// lifetime of the returned reference.144unsafe { &mut *ptr.cast() }145}146147/// Returns a raw pointer to the underlying C `cpufreq_policy_data`.148#[inline]149pub fn as_raw(&self) -> *mut bindings::cpufreq_policy_data {150let this: *const Self = self;151this.cast_mut().cast()152}153154/// Wrapper for `cpufreq_generic_frequency_table_verify`.155#[inline]156pub fn generic_verify(&self) -> Result {157// SAFETY: By the type invariant, the pointer stored in `self` is valid.158to_result(unsafe { bindings::cpufreq_generic_frequency_table_verify(self.as_raw()) })159}160}161162/// The frequency table index.163///164/// Represents index with a frequency table.165///166/// # Invariants167///168/// The index must correspond to a valid entry in the [`Table`] it is used for.169#[derive(Copy, Clone, PartialEq, Eq, Debug)]170pub struct TableIndex(usize);171172impl TableIndex {173/// Creates an instance of [`TableIndex`].174///175/// # Safety176///177/// The caller must ensure that `index` correspond to a valid entry in the [`Table`] it is used178/// for.179pub unsafe fn new(index: usize) -> Self {180// INVARIANT: The caller ensures that `index` correspond to a valid entry in the [`Table`].181Self(index)182}183}184185impl From<TableIndex> for usize {186#[inline]187fn from(index: TableIndex) -> Self {188index.0189}190}191192/// CPU frequency table.193///194/// Rust abstraction for the C `struct cpufreq_frequency_table`.195///196/// # Invariants197///198/// A [`Table`] instance always corresponds to a valid C `struct cpufreq_frequency_table`.199///200/// The callers must ensure that the `struct cpufreq_frequency_table` is valid for access and201/// remains valid for the lifetime of the returned reference.202///203/// # Examples204///205/// The following example demonstrates how to read a frequency value from [`Table`].206///207/// ```208/// use kernel::cpufreq::{Policy, TableIndex};209///210/// fn show_freq(policy: &Policy) -> Result {211/// let table = policy.freq_table()?;212///213/// // SAFETY: Index is a valid entry in the table.214/// let index = unsafe { TableIndex::new(0) };215///216/// pr_info!("The frequency at index 0 is: {:?}\n", table.freq(index)?);217/// pr_info!("The flags at index 0 is: {}\n", table.flags(index));218/// pr_info!("The data at index 0 is: {}\n", table.data(index));219/// Ok(())220/// }221/// ```222#[repr(transparent)]223pub struct Table(Opaque<bindings::cpufreq_frequency_table>);224225impl Table {226/// Creates a reference to an existing C `struct cpufreq_frequency_table` pointer.227///228/// # Safety229///230/// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime231/// of the returned reference.232#[inline]233pub unsafe fn from_raw<'a>(ptr: *const bindings::cpufreq_frequency_table) -> &'a Self {234// SAFETY: Guaranteed by the safety requirements of the function.235//236// INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the237// lifetime of the returned reference.238unsafe { &*ptr.cast() }239}240241/// Returns the raw mutable pointer to the C `struct cpufreq_frequency_table`.242#[inline]243pub fn as_raw(&self) -> *mut bindings::cpufreq_frequency_table {244let this: *const Self = self;245this.cast_mut().cast()246}247248/// Returns frequency at `index` in the [`Table`].249#[inline]250pub fn freq(&self, index: TableIndex) -> Result<Hertz> {251// SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is252// guaranteed to be valid by its safety requirements.253Ok(Hertz::from_khz(unsafe {254(*self.as_raw().add(index.into())).frequency.try_into()?255}))256}257258/// Returns flags at `index` in the [`Table`].259#[inline]260pub fn flags(&self, index: TableIndex) -> u32 {261// SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is262// guaranteed to be valid by its safety requirements.263unsafe { (*self.as_raw().add(index.into())).flags }264}265266/// Returns data at `index` in the [`Table`].267#[inline]268pub fn data(&self, index: TableIndex) -> u32 {269// SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is270// guaranteed to be valid by its safety requirements.271unsafe { (*self.as_raw().add(index.into())).driver_data }272}273}274275/// CPU frequency table owned and pinned in memory, created from a [`TableBuilder`].276pub struct TableBox {277entries: Pin<KVec<bindings::cpufreq_frequency_table>>,278}279280impl TableBox {281/// Constructs a new [`TableBox`] from a [`KVec`] of entries.282///283/// # Errors284///285/// Returns `EINVAL` if the entries list is empty.286#[inline]287fn new(entries: KVec<bindings::cpufreq_frequency_table>) -> Result<Self> {288if entries.is_empty() {289return Err(EINVAL);290}291292Ok(Self {293// Pin the entries to memory, since we are passing its pointer to the C code.294entries: Pin::new(entries),295})296}297298/// Returns a raw pointer to the underlying C `cpufreq_frequency_table`.299#[inline]300fn as_raw(&self) -> *const bindings::cpufreq_frequency_table {301// The pointer is valid until the table gets dropped.302self.entries.as_ptr()303}304}305306impl Deref for TableBox {307type Target = Table;308309fn deref(&self) -> &Self::Target {310// SAFETY: The caller owns TableBox, it is safe to deref.311unsafe { Self::Target::from_raw(self.as_raw()) }312}313}314315/// CPU frequency table builder.316///317/// This is used by the CPU frequency drivers to build a frequency table dynamically.318///319/// # Examples320///321/// The following example demonstrates how to create a CPU frequency table.322///323/// ```324/// use kernel::cpufreq::{TableBuilder, TableIndex};325/// use kernel::clk::Hertz;326///327/// let mut builder = TableBuilder::new();328///329/// // Adds few entries to the table.330/// builder.add(Hertz::from_mhz(700), 0, 1).unwrap();331/// builder.add(Hertz::from_mhz(800), 2, 3).unwrap();332/// builder.add(Hertz::from_mhz(900), 4, 5).unwrap();333/// builder.add(Hertz::from_ghz(1), 6, 7).unwrap();334///335/// let table = builder.to_table().unwrap();336///337/// // SAFETY: Index values correspond to valid entries in the table.338/// let (index0, index2) = unsafe { (TableIndex::new(0), TableIndex::new(2)) };339///340/// assert_eq!(table.freq(index0), Ok(Hertz::from_mhz(700)));341/// assert_eq!(table.flags(index0), 0);342/// assert_eq!(table.data(index0), 1);343///344/// assert_eq!(table.freq(index2), Ok(Hertz::from_mhz(900)));345/// assert_eq!(table.flags(index2), 4);346/// assert_eq!(table.data(index2), 5);347/// ```348#[derive(Default)]349#[repr(transparent)]350pub struct TableBuilder {351entries: KVec<bindings::cpufreq_frequency_table>,352}353354impl TableBuilder {355/// Creates a new instance of [`TableBuilder`].356#[inline]357pub fn new() -> Self {358Self {359entries: KVec::new(),360}361}362363/// Adds a new entry to the table.364pub fn add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result {365// Adds the new entry at the end of the vector.366Ok(self.entries.push(367bindings::cpufreq_frequency_table {368flags,369driver_data,370frequency: freq.as_khz() as u32,371},372GFP_KERNEL,373)?)374}375376/// Consumes the [`TableBuilder`] and returns [`TableBox`].377pub fn to_table(mut self) -> Result<TableBox> {378// Add last entry to the table.379self.add(Hertz(c_ulong::MAX), 0, 0)?;380381TableBox::new(self.entries)382}383}384385/// CPU frequency policy.386///387/// Rust abstraction for the C `struct cpufreq_policy`.388///389/// # Invariants390///391/// A [`Policy`] instance always corresponds to a valid C `struct cpufreq_policy`.392///393/// The callers must ensure that the `struct cpufreq_policy` is valid for access and remains valid394/// for the lifetime of the returned reference.395///396/// # Examples397///398/// The following example demonstrates how to create a CPU frequency table.399///400/// ```401/// use kernel::cpufreq::{ETERNAL_LATENCY_NS, Policy};402///403/// fn update_policy(policy: &mut Policy) {404/// policy405/// .set_dvfs_possible_from_any_cpu(true)406/// .set_fast_switch_possible(true)407/// .set_transition_latency_ns(ETERNAL_LATENCY_NS);408///409/// pr_info!("The policy details are: {:?}\n", (policy.cpu(), policy.cur()));410/// }411/// ```412#[repr(transparent)]413pub struct Policy(Opaque<bindings::cpufreq_policy>);414415impl Policy {416/// Creates a reference to an existing `struct cpufreq_policy` pointer.417///418/// # Safety419///420/// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime421/// of the returned reference.422#[inline]423pub unsafe fn from_raw<'a>(ptr: *const bindings::cpufreq_policy) -> &'a Self {424// SAFETY: Guaranteed by the safety requirements of the function.425//426// INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the427// lifetime of the returned reference.428unsafe { &*ptr.cast() }429}430431/// Creates a mutable reference to an existing `struct cpufreq_policy` pointer.432///433/// # Safety434///435/// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime436/// of the returned reference.437#[inline]438pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy) -> &'a mut Self {439// SAFETY: Guaranteed by the safety requirements of the function.440//441// INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the442// lifetime of the returned reference.443unsafe { &mut *ptr.cast() }444}445446/// Returns a raw mutable pointer to the C `struct cpufreq_policy`.447#[inline]448fn as_raw(&self) -> *mut bindings::cpufreq_policy {449let this: *const Self = self;450this.cast_mut().cast()451}452453#[inline]454fn as_ref(&self) -> &bindings::cpufreq_policy {455// SAFETY: By the type invariant, the pointer stored in `self` is valid.456unsafe { &*self.as_raw() }457}458459#[inline]460fn as_mut_ref(&mut self) -> &mut bindings::cpufreq_policy {461// SAFETY: By the type invariant, the pointer stored in `self` is valid.462unsafe { &mut *self.as_raw() }463}464465/// Returns the primary CPU for the [`Policy`].466#[inline]467pub fn cpu(&self) -> CpuId {468// SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.469unsafe { CpuId::from_u32_unchecked(self.as_ref().cpu) }470}471472/// Returns the minimum frequency for the [`Policy`].473#[inline]474pub fn min(&self) -> Hertz {475Hertz::from_khz(self.as_ref().min as usize)476}477478/// Set the minimum frequency for the [`Policy`].479#[inline]480pub fn set_min(&mut self, min: Hertz) -> &mut Self {481self.as_mut_ref().min = min.as_khz() as u32;482self483}484485/// Returns the maximum frequency for the [`Policy`].486#[inline]487pub fn max(&self) -> Hertz {488Hertz::from_khz(self.as_ref().max as usize)489}490491/// Set the maximum frequency for the [`Policy`].492#[inline]493pub fn set_max(&mut self, max: Hertz) -> &mut Self {494self.as_mut_ref().max = max.as_khz() as u32;495self496}497498/// Returns the current frequency for the [`Policy`].499#[inline]500pub fn cur(&self) -> Hertz {501Hertz::from_khz(self.as_ref().cur as usize)502}503504/// Returns the suspend frequency for the [`Policy`].505#[inline]506pub fn suspend_freq(&self) -> Hertz {507Hertz::from_khz(self.as_ref().suspend_freq as usize)508}509510/// Sets the suspend frequency for the [`Policy`].511#[inline]512pub fn set_suspend_freq(&mut self, freq: Hertz) -> &mut Self {513self.as_mut_ref().suspend_freq = freq.as_khz() as u32;514self515}516517/// Provides a wrapper to the generic suspend routine.518#[inline]519pub fn generic_suspend(&mut self) -> Result {520// SAFETY: By the type invariant, the pointer stored in `self` is valid.521to_result(unsafe { bindings::cpufreq_generic_suspend(self.as_mut_ref()) })522}523524/// Provides a wrapper to the generic get routine.525#[inline]526pub fn generic_get(&self) -> Result<u32> {527// SAFETY: By the type invariant, the pointer stored in `self` is valid.528Ok(unsafe { bindings::cpufreq_generic_get(u32::from(self.cpu())) })529}530531/// Provides a wrapper to the register with energy model using the OPP core.532#[cfg(CONFIG_PM_OPP)]533#[inline]534pub fn register_em_opp(&mut self) {535// SAFETY: By the type invariant, the pointer stored in `self` is valid.536unsafe { bindings::cpufreq_register_em_with_opp(self.as_mut_ref()) };537}538539/// Gets [`cpumask::Cpumask`] for a cpufreq [`Policy`].540#[inline]541pub fn cpus(&mut self) -> &mut cpumask::Cpumask {542// SAFETY: The pointer to `cpus` is valid for writing and remains valid for the lifetime of543// the returned reference.544unsafe { cpumask::CpumaskVar::from_raw_mut(&mut self.as_mut_ref().cpus) }545}546547/// Sets clock for the [`Policy`].548///549/// # Safety550///551/// The caller must guarantee that the returned [`Clk`] is not dropped while it is getting used552/// by the C code.553#[cfg(CONFIG_COMMON_CLK)]554pub unsafe fn set_clk(&mut self, dev: &Device, name: Option<&CStr>) -> Result<Clk> {555let clk = Clk::get(dev, name)?;556self.as_mut_ref().clk = clk.as_raw();557Ok(clk)558}559560/// Allows / disallows frequency switching code to run on any CPU.561#[inline]562pub fn set_dvfs_possible_from_any_cpu(&mut self, val: bool) -> &mut Self {563self.as_mut_ref().dvfs_possible_from_any_cpu = val;564self565}566567/// Returns if fast switching of frequencies is possible or not.568#[inline]569pub fn fast_switch_possible(&self) -> bool {570self.as_ref().fast_switch_possible571}572573/// Enables / disables fast frequency switching.574#[inline]575pub fn set_fast_switch_possible(&mut self, val: bool) -> &mut Self {576self.as_mut_ref().fast_switch_possible = val;577self578}579580/// Sets transition latency (in nanoseconds) for the [`Policy`].581#[inline]582pub fn set_transition_latency_ns(&mut self, latency_ns: u32) -> &mut Self {583self.as_mut_ref().cpuinfo.transition_latency = latency_ns;584self585}586587/// Sets cpuinfo `min_freq`.588#[inline]589pub fn set_cpuinfo_min_freq(&mut self, min_freq: Hertz) -> &mut Self {590self.as_mut_ref().cpuinfo.min_freq = min_freq.as_khz() as u32;591self592}593594/// Sets cpuinfo `max_freq`.595#[inline]596pub fn set_cpuinfo_max_freq(&mut self, max_freq: Hertz) -> &mut Self {597self.as_mut_ref().cpuinfo.max_freq = max_freq.as_khz() as u32;598self599}600601/// Set `transition_delay_us`, i.e. the minimum time between successive frequency change602/// requests.603#[inline]604pub fn set_transition_delay_us(&mut self, transition_delay_us: u32) -> &mut Self {605self.as_mut_ref().transition_delay_us = transition_delay_us;606self607}608609/// Returns reference to the CPU frequency [`Table`] for the [`Policy`].610pub fn freq_table(&self) -> Result<&Table> {611if self.as_ref().freq_table.is_null() {612return Err(EINVAL);613}614615// SAFETY: The `freq_table` is guaranteed to be valid for reading and remains valid for the616// lifetime of the returned reference.617Ok(unsafe { Table::from_raw(self.as_ref().freq_table) })618}619620/// Sets the CPU frequency [`Table`] for the [`Policy`].621///622/// # Safety623///624/// The caller must guarantee that the [`Table`] is not dropped while it is getting used by the625/// C code.626#[inline]627pub unsafe fn set_freq_table(&mut self, table: &Table) -> &mut Self {628self.as_mut_ref().freq_table = table.as_raw();629self630}631632/// Returns the [`Policy`]'s private data.633pub fn data<T: ForeignOwnable>(&mut self) -> Option<<T>::Borrowed<'_>> {634if self.as_ref().driver_data.is_null() {635None636} else {637// SAFETY: The data is earlier set from [`set_data`].638Some(unsafe { T::borrow(self.as_ref().driver_data.cast()) })639}640}641642/// Sets the private data of the [`Policy`] using a foreign-ownable wrapper.643///644/// # Errors645///646/// Returns `EBUSY` if private data is already set.647fn set_data<T: ForeignOwnable>(&mut self, data: T) -> Result {648if self.as_ref().driver_data.is_null() {649// Transfer the ownership of the data to the foreign interface.650self.as_mut_ref().driver_data = <T as ForeignOwnable>::into_foreign(data).cast();651Ok(())652} else {653Err(EBUSY)654}655}656657/// Clears and returns ownership of the private data.658fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> {659if self.as_ref().driver_data.is_null() {660None661} else {662let data = Some(663// SAFETY: The data is earlier set by us from [`set_data`]. It is safe to take664// back the ownership of the data from the foreign interface.665unsafe { <T as ForeignOwnable>::from_foreign(self.as_ref().driver_data.cast()) },666);667self.as_mut_ref().driver_data = ptr::null_mut();668data669}670}671}672673/// CPU frequency policy created from a CPU number.674///675/// This struct represents the CPU frequency policy obtained for a specific CPU, providing safe676/// access to the underlying `cpufreq_policy` and ensuring proper cleanup when the `PolicyCpu` is677/// dropped.678struct PolicyCpu<'a>(&'a mut Policy);679680impl<'a> PolicyCpu<'a> {681fn from_cpu(cpu: CpuId) -> Result<Self> {682// SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU.683let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) })?;684685Ok(Self(686// SAFETY: The `ptr` is guaranteed to be valid and remains valid for the lifetime of687// the returned reference.688unsafe { Policy::from_raw_mut(ptr) },689))690}691}692693impl<'a> Deref for PolicyCpu<'a> {694type Target = Policy;695696fn deref(&self) -> &Self::Target {697self.0698}699}700701impl<'a> DerefMut for PolicyCpu<'a> {702fn deref_mut(&mut self) -> &mut Policy {703self.0704}705}706707impl<'a> Drop for PolicyCpu<'a> {708fn drop(&mut self) {709// SAFETY: The underlying pointer is guaranteed to be valid for the lifetime of `self`.710unsafe { bindings::cpufreq_cpu_put(self.0.as_raw()) };711}712}713714/// CPU frequency driver.715///716/// Implement this trait to provide a CPU frequency driver and its callbacks.717///718/// Reference: <https://docs.kernel.org/cpu-freq/cpu-drivers.html>719#[vtable]720pub trait Driver {721/// Driver's name.722const NAME: &'static CStr;723724/// Driver's flags.725const FLAGS: u16;726727/// Boost support.728const BOOST_ENABLED: bool;729730/// Policy specific data.731///732/// Require that `PData` implements `ForeignOwnable`. We guarantee to never move the underlying733/// wrapped data structure.734type PData: ForeignOwnable;735736/// Driver's `init` callback.737fn init(policy: &mut Policy) -> Result<Self::PData>;738739/// Driver's `exit` callback.740fn exit(_policy: &mut Policy, _data: Option<Self::PData>) -> Result {741build_error!(VTABLE_DEFAULT_ERROR)742}743744/// Driver's `online` callback.745fn online(_policy: &mut Policy) -> Result {746build_error!(VTABLE_DEFAULT_ERROR)747}748749/// Driver's `offline` callback.750fn offline(_policy: &mut Policy) -> Result {751build_error!(VTABLE_DEFAULT_ERROR)752}753754/// Driver's `suspend` callback.755fn suspend(_policy: &mut Policy) -> Result {756build_error!(VTABLE_DEFAULT_ERROR)757}758759/// Driver's `resume` callback.760fn resume(_policy: &mut Policy) -> Result {761build_error!(VTABLE_DEFAULT_ERROR)762}763764/// Driver's `ready` callback.765fn ready(_policy: &mut Policy) {766build_error!(VTABLE_DEFAULT_ERROR)767}768769/// Driver's `verify` callback.770fn verify(data: &mut PolicyData) -> Result;771772/// Driver's `setpolicy` callback.773fn setpolicy(_policy: &mut Policy) -> Result {774build_error!(VTABLE_DEFAULT_ERROR)775}776777/// Driver's `target` callback.778fn target(_policy: &mut Policy, _target_freq: u32, _relation: Relation) -> Result {779build_error!(VTABLE_DEFAULT_ERROR)780}781782/// Driver's `target_index` callback.783fn target_index(_policy: &mut Policy, _index: TableIndex) -> Result {784build_error!(VTABLE_DEFAULT_ERROR)785}786787/// Driver's `fast_switch` callback.788fn fast_switch(_policy: &mut Policy, _target_freq: u32) -> u32 {789build_error!(VTABLE_DEFAULT_ERROR)790}791792/// Driver's `adjust_perf` callback.793fn adjust_perf(_policy: &mut Policy, _min_perf: usize, _target_perf: usize, _capacity: usize) {794build_error!(VTABLE_DEFAULT_ERROR)795}796797/// Driver's `get_intermediate` callback.798fn get_intermediate(_policy: &mut Policy, _index: TableIndex) -> u32 {799build_error!(VTABLE_DEFAULT_ERROR)800}801802/// Driver's `target_intermediate` callback.803fn target_intermediate(_policy: &mut Policy, _index: TableIndex) -> Result {804build_error!(VTABLE_DEFAULT_ERROR)805}806807/// Driver's `get` callback.808fn get(_policy: &mut Policy) -> Result<u32> {809build_error!(VTABLE_DEFAULT_ERROR)810}811812/// Driver's `update_limits` callback.813fn update_limits(_policy: &mut Policy) {814build_error!(VTABLE_DEFAULT_ERROR)815}816817/// Driver's `bios_limit` callback.818fn bios_limit(_policy: &mut Policy, _limit: &mut u32) -> Result {819build_error!(VTABLE_DEFAULT_ERROR)820}821822/// Driver's `set_boost` callback.823fn set_boost(_policy: &mut Policy, _state: i32) -> Result {824build_error!(VTABLE_DEFAULT_ERROR)825}826827/// Driver's `register_em` callback.828fn register_em(_policy: &mut Policy) {829build_error!(VTABLE_DEFAULT_ERROR)830}831}832833/// CPU frequency driver Registration.834///835/// # Examples836///837/// The following example demonstrates how to register a cpufreq driver.838///839/// ```840/// use kernel::{841/// cpufreq,842/// c_str,843/// device::{Core, Device},844/// macros::vtable,845/// of, platform,846/// sync::Arc,847/// };848/// struct SampleDevice;849///850/// #[derive(Default)]851/// struct SampleDriver;852///853/// #[vtable]854/// impl cpufreq::Driver for SampleDriver {855/// const NAME: &'static CStr = c_str!("cpufreq-sample");856/// const FLAGS: u16 = cpufreq::flags::NEED_INITIAL_FREQ_CHECK | cpufreq::flags::IS_COOLING_DEV;857/// const BOOST_ENABLED: bool = true;858///859/// type PData = Arc<SampleDevice>;860///861/// fn init(policy: &mut cpufreq::Policy) -> Result<Self::PData> {862/// // Initialize here863/// Ok(Arc::new(SampleDevice, GFP_KERNEL)?)864/// }865///866/// fn exit(_policy: &mut cpufreq::Policy, _data: Option<Self::PData>) -> Result {867/// Ok(())868/// }869///870/// fn suspend(policy: &mut cpufreq::Policy) -> Result {871/// policy.generic_suspend()872/// }873///874/// fn verify(data: &mut cpufreq::PolicyData) -> Result {875/// data.generic_verify()876/// }877///878/// fn target_index(policy: &mut cpufreq::Policy, index: cpufreq::TableIndex) -> Result {879/// // Update CPU frequency880/// Ok(())881/// }882///883/// fn get(policy: &mut cpufreq::Policy) -> Result<u32> {884/// policy.generic_get()885/// }886/// }887///888/// impl platform::Driver for SampleDriver {889/// type IdInfo = ();890/// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;891///892/// fn probe(893/// pdev: &platform::Device<Core>,894/// _id_info: Option<&Self::IdInfo>,895/// ) -> Result<Pin<KBox<Self>>> {896/// cpufreq::Registration::<SampleDriver>::new_foreign_owned(pdev.as_ref())?;897/// Ok(KBox::new(Self {}, GFP_KERNEL)?.into())898/// }899/// }900/// ```901#[repr(transparent)]902pub struct Registration<T: Driver>(KBox<UnsafeCell<bindings::cpufreq_driver>>, PhantomData<T>);903904/// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between threads905/// or CPUs, so it is safe to share it.906unsafe impl<T: Driver> Sync for Registration<T> {}907908#[allow(clippy::non_send_fields_in_send_ty)]909/// SAFETY: Registration with and unregistration from the cpufreq subsystem can happen from any910/// thread.911unsafe impl<T: Driver> Send for Registration<T> {}912913impl<T: Driver> Registration<T> {914const VTABLE: bindings::cpufreq_driver = bindings::cpufreq_driver {915name: Self::copy_name(T::NAME),916boost_enabled: T::BOOST_ENABLED,917flags: T::FLAGS,918919// Initialize mandatory callbacks.920init: Some(Self::init_callback),921verify: Some(Self::verify_callback),922923// Initialize optional callbacks based on the traits of `T`.924setpolicy: if T::HAS_SETPOLICY {925Some(Self::setpolicy_callback)926} else {927None928},929target: if T::HAS_TARGET {930Some(Self::target_callback)931} else {932None933},934target_index: if T::HAS_TARGET_INDEX {935Some(Self::target_index_callback)936} else {937None938},939fast_switch: if T::HAS_FAST_SWITCH {940Some(Self::fast_switch_callback)941} else {942None943},944adjust_perf: if T::HAS_ADJUST_PERF {945Some(Self::adjust_perf_callback)946} else {947None948},949get_intermediate: if T::HAS_GET_INTERMEDIATE {950Some(Self::get_intermediate_callback)951} else {952None953},954target_intermediate: if T::HAS_TARGET_INTERMEDIATE {955Some(Self::target_intermediate_callback)956} else {957None958},959get: if T::HAS_GET {960Some(Self::get_callback)961} else {962None963},964update_limits: if T::HAS_UPDATE_LIMITS {965Some(Self::update_limits_callback)966} else {967None968},969bios_limit: if T::HAS_BIOS_LIMIT {970Some(Self::bios_limit_callback)971} else {972None973},974online: if T::HAS_ONLINE {975Some(Self::online_callback)976} else {977None978},979offline: if T::HAS_OFFLINE {980Some(Self::offline_callback)981} else {982None983},984exit: if T::HAS_EXIT {985Some(Self::exit_callback)986} else {987None988},989suspend: if T::HAS_SUSPEND {990Some(Self::suspend_callback)991} else {992None993},994resume: if T::HAS_RESUME {995Some(Self::resume_callback)996} else {997None998},999ready: if T::HAS_READY {1000Some(Self::ready_callback)1001} else {1002None1003},1004set_boost: if T::HAS_SET_BOOST {1005Some(Self::set_boost_callback)1006} else {1007None1008},1009register_em: if T::HAS_REGISTER_EM {1010Some(Self::register_em_callback)1011} else {1012None1013},1014..pin_init::zeroed()1015};10161017const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] {1018let src = name.to_bytes_with_nul();1019let mut dst = [0; CPUFREQ_NAME_LEN];10201021build_assert!(src.len() <= CPUFREQ_NAME_LEN);10221023let mut i = 0;1024while i < src.len() {1025dst[i] = src[i];1026i += 1;1027}10281029dst1030}10311032/// Registers a CPU frequency driver with the cpufreq core.1033pub fn new() -> Result<Self> {1034// We can't use `&Self::VTABLE` directly because the cpufreq core modifies some fields in1035// the C `struct cpufreq_driver`, which requires a mutable reference.1036let mut drv = KBox::new(UnsafeCell::new(Self::VTABLE), GFP_KERNEL)?;10371038// SAFETY: `drv` is guaranteed to be valid for the lifetime of `Registration`.1039to_result(unsafe { bindings::cpufreq_register_driver(drv.get_mut()) })?;10401041Ok(Self(drv, PhantomData))1042}10431044/// Same as [`Registration::new`], but does not return a [`Registration`] instance.1045///1046/// Instead the [`Registration`] is owned by [`devres::register`] and will be dropped, once the1047/// device is detached.1048pub fn new_foreign_owned(dev: &Device<Bound>) -> Result1049where1050T: 'static,1051{1052devres::register(dev, Self::new()?, GFP_KERNEL)1053}1054}10551056/// CPU frequency driver callbacks.1057impl<T: Driver> Registration<T> {1058/// Driver's `init` callback.1059///1060/// # Safety1061///1062/// - This function may only be called from the cpufreq C infrastructure.1063/// - The pointer arguments must be valid pointers.1064unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1065from_result(|| {1066// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1067// lifetime of `policy`.1068let policy = unsafe { Policy::from_raw_mut(ptr) };10691070let data = T::init(policy)?;1071policy.set_data(data)?;1072Ok(0)1073})1074}10751076/// Driver's `exit` callback.1077///1078/// # Safety1079///1080/// - This function may only be called from the cpufreq C infrastructure.1081/// - The pointer arguments must be valid pointers.1082unsafe extern "C" fn exit_callback(ptr: *mut bindings::cpufreq_policy) {1083// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1084// lifetime of `policy`.1085let policy = unsafe { Policy::from_raw_mut(ptr) };10861087let data = policy.clear_data();1088let _ = T::exit(policy, data);1089}10901091/// Driver's `online` callback.1092///1093/// # Safety1094///1095/// - This function may only be called from the cpufreq C infrastructure.1096/// - The pointer arguments must be valid pointers.1097unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1098from_result(|| {1099// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1100// lifetime of `policy`.1101let policy = unsafe { Policy::from_raw_mut(ptr) };1102T::online(policy).map(|()| 0)1103})1104}11051106/// Driver's `offline` callback.1107///1108/// # Safety1109///1110/// - This function may only be called from the cpufreq C infrastructure.1111/// - The pointer arguments must be valid pointers.1112unsafe extern "C" fn offline_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1113from_result(|| {1114// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1115// lifetime of `policy`.1116let policy = unsafe { Policy::from_raw_mut(ptr) };1117T::offline(policy).map(|()| 0)1118})1119}11201121/// Driver's `suspend` callback.1122///1123/// # Safety1124///1125/// - This function may only be called from the cpufreq C infrastructure.1126/// - The pointer arguments must be valid pointers.1127unsafe extern "C" fn suspend_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1128from_result(|| {1129// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1130// lifetime of `policy`.1131let policy = unsafe { Policy::from_raw_mut(ptr) };1132T::suspend(policy).map(|()| 0)1133})1134}11351136/// Driver's `resume` callback.1137///1138/// # Safety1139///1140/// - This function may only be called from the cpufreq C infrastructure.1141/// - The pointer arguments must be valid pointers.1142unsafe extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1143from_result(|| {1144// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1145// lifetime of `policy`.1146let policy = unsafe { Policy::from_raw_mut(ptr) };1147T::resume(policy).map(|()| 0)1148})1149}11501151/// Driver's `ready` callback.1152///1153/// # Safety1154///1155/// - This function may only be called from the cpufreq C infrastructure.1156/// - The pointer arguments must be valid pointers.1157unsafe extern "C" fn ready_callback(ptr: *mut bindings::cpufreq_policy) {1158// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1159// lifetime of `policy`.1160let policy = unsafe { Policy::from_raw_mut(ptr) };1161T::ready(policy);1162}11631164/// Driver's `verify` callback.1165///1166/// # Safety1167///1168/// - This function may only be called from the cpufreq C infrastructure.1169/// - The pointer arguments must be valid pointers.1170unsafe extern "C" fn verify_callback(ptr: *mut bindings::cpufreq_policy_data) -> c_int {1171from_result(|| {1172// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1173// lifetime of `policy`.1174let data = unsafe { PolicyData::from_raw_mut(ptr) };1175T::verify(data).map(|()| 0)1176})1177}11781179/// Driver's `setpolicy` callback.1180///1181/// # Safety1182///1183/// - This function may only be called from the cpufreq C infrastructure.1184/// - The pointer arguments must be valid pointers.1185unsafe extern "C" fn setpolicy_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1186from_result(|| {1187// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1188// lifetime of `policy`.1189let policy = unsafe { Policy::from_raw_mut(ptr) };1190T::setpolicy(policy).map(|()| 0)1191})1192}11931194/// Driver's `target` callback.1195///1196/// # Safety1197///1198/// - This function may only be called from the cpufreq C infrastructure.1199/// - The pointer arguments must be valid pointers.1200unsafe extern "C" fn target_callback(1201ptr: *mut bindings::cpufreq_policy,1202target_freq: c_uint,1203relation: c_uint,1204) -> c_int {1205from_result(|| {1206// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1207// lifetime of `policy`.1208let policy = unsafe { Policy::from_raw_mut(ptr) };1209T::target(policy, target_freq, Relation::new(relation)?).map(|()| 0)1210})1211}12121213/// Driver's `target_index` callback.1214///1215/// # Safety1216///1217/// - This function may only be called from the cpufreq C infrastructure.1218/// - The pointer arguments must be valid pointers.1219unsafe extern "C" fn target_index_callback(1220ptr: *mut bindings::cpufreq_policy,1221index: c_uint,1222) -> c_int {1223from_result(|| {1224// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1225// lifetime of `policy`.1226let policy = unsafe { Policy::from_raw_mut(ptr) };12271228// SAFETY: The C code guarantees that `index` corresponds to a valid entry in the1229// frequency table.1230let index = unsafe { TableIndex::new(index as usize) };12311232T::target_index(policy, index).map(|()| 0)1233})1234}12351236/// Driver's `fast_switch` callback.1237///1238/// # Safety1239///1240/// - This function may only be called from the cpufreq C infrastructure.1241/// - The pointer arguments must be valid pointers.1242unsafe extern "C" fn fast_switch_callback(1243ptr: *mut bindings::cpufreq_policy,1244target_freq: c_uint,1245) -> c_uint {1246// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1247// lifetime of `policy`.1248let policy = unsafe { Policy::from_raw_mut(ptr) };1249T::fast_switch(policy, target_freq)1250}12511252/// Driver's `adjust_perf` callback.1253///1254/// # Safety1255///1256/// - This function may only be called from the cpufreq C infrastructure.1257unsafe extern "C" fn adjust_perf_callback(1258cpu: c_uint,1259min_perf: c_ulong,1260target_perf: c_ulong,1261capacity: c_ulong,1262) {1263// SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.1264let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };12651266if let Ok(mut policy) = PolicyCpu::from_cpu(cpu_id) {1267T::adjust_perf(&mut policy, min_perf, target_perf, capacity);1268}1269}12701271/// Driver's `get_intermediate` callback.1272///1273/// # Safety1274///1275/// - This function may only be called from the cpufreq C infrastructure.1276/// - The pointer arguments must be valid pointers.1277unsafe extern "C" fn get_intermediate_callback(1278ptr: *mut bindings::cpufreq_policy,1279index: c_uint,1280) -> c_uint {1281// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1282// lifetime of `policy`.1283let policy = unsafe { Policy::from_raw_mut(ptr) };12841285// SAFETY: The C code guarantees that `index` corresponds to a valid entry in the1286// frequency table.1287let index = unsafe { TableIndex::new(index as usize) };12881289T::get_intermediate(policy, index)1290}12911292/// Driver's `target_intermediate` callback.1293///1294/// # Safety1295///1296/// - This function may only be called from the cpufreq C infrastructure.1297/// - The pointer arguments must be valid pointers.1298unsafe extern "C" fn target_intermediate_callback(1299ptr: *mut bindings::cpufreq_policy,1300index: c_uint,1301) -> c_int {1302from_result(|| {1303// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1304// lifetime of `policy`.1305let policy = unsafe { Policy::from_raw_mut(ptr) };13061307// SAFETY: The C code guarantees that `index` corresponds to a valid entry in the1308// frequency table.1309let index = unsafe { TableIndex::new(index as usize) };13101311T::target_intermediate(policy, index).map(|()| 0)1312})1313}13141315/// Driver's `get` callback.1316///1317/// # Safety1318///1319/// - This function may only be called from the cpufreq C infrastructure.1320unsafe extern "C" fn get_callback(cpu: c_uint) -> c_uint {1321// SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.1322let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };13231324PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))1325}13261327/// Driver's `update_limit` callback.1328///1329/// # Safety1330///1331/// - This function may only be called from the cpufreq C infrastructure.1332/// - The pointer arguments must be valid pointers.1333unsafe extern "C" fn update_limits_callback(ptr: *mut bindings::cpufreq_policy) {1334// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1335// lifetime of `policy`.1336let policy = unsafe { Policy::from_raw_mut(ptr) };1337T::update_limits(policy);1338}13391340/// Driver's `bios_limit` callback.1341///1342/// # Safety1343///1344/// - This function may only be called from the cpufreq C infrastructure.1345/// - The pointer arguments must be valid pointers.1346unsafe extern "C" fn bios_limit_callback(cpu: c_int, limit: *mut c_uint) -> c_int {1347// SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.1348let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) };13491350from_result(|| {1351let mut policy = PolicyCpu::from_cpu(cpu_id)?;13521353// SAFETY: `limit` is guaranteed by the C code to be valid.1354T::bios_limit(&mut policy, &mut (unsafe { *limit })).map(|()| 0)1355})1356}13571358/// Driver's `set_boost` callback.1359///1360/// # Safety1361///1362/// - This function may only be called from the cpufreq C infrastructure.1363/// - The pointer arguments must be valid pointers.1364unsafe extern "C" fn set_boost_callback(1365ptr: *mut bindings::cpufreq_policy,1366state: c_int,1367) -> c_int {1368from_result(|| {1369// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1370// lifetime of `policy`.1371let policy = unsafe { Policy::from_raw_mut(ptr) };1372T::set_boost(policy, state).map(|()| 0)1373})1374}13751376/// Driver's `register_em` callback.1377///1378/// # Safety1379///1380/// - This function may only be called from the cpufreq C infrastructure.1381/// - The pointer arguments must be valid pointers.1382unsafe extern "C" fn register_em_callback(ptr: *mut bindings::cpufreq_policy) {1383// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1384// lifetime of `policy`.1385let policy = unsafe { Policy::from_raw_mut(ptr) };1386T::register_em(policy);1387}1388}13891390impl<T: Driver> Drop for Registration<T> {1391/// Unregisters with the cpufreq core.1392fn drop(&mut self) {1393// SAFETY: `self.0` is guaranteed to be valid for the lifetime of `Registration`.1394unsafe { bindings::cpufreq_unregister_driver(self.0.get_mut()) };1395}1396}139713981399