// 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 DEFAULT_TRANSITION_LATENCY_NS: u32 =41bindings::CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS;4243/// CPU frequency driver flags.44pub mod flags {45/// Driver needs to update internal limits even if frequency remains unchanged.46pub const NEED_UPDATE_LIMITS: u16 = 1 << 0;4748/// Platform where constants like `loops_per_jiffy` are unaffected by frequency changes.49pub const CONST_LOOPS: u16 = 1 << 1;5051/// Register driver as a thermal cooling device automatically.52pub const IS_COOLING_DEV: u16 = 1 << 2;5354/// Supports multiple clock domains with per-policy governors in `cpu/cpuN/cpufreq/`.55pub const HAVE_GOVERNOR_PER_POLICY: u16 = 1 << 3;5657/// Allows post-change notifications outside of the `target()` routine.58pub const ASYNC_NOTIFICATION: u16 = 1 << 4;5960/// Ensure CPU starts at a valid frequency from the driver's freq-table.61pub const NEED_INITIAL_FREQ_CHECK: u16 = 1 << 5;6263/// Disallow governors with `dynamic_switching` capability.64pub const NO_AUTO_DYNAMIC_SWITCHING: u16 = 1 << 6;65}6667/// Relations from the C code.68const CPUFREQ_RELATION_L: u32 = 0;69const CPUFREQ_RELATION_H: u32 = 1;70const CPUFREQ_RELATION_C: u32 = 2;7172/// Can be used with any of the above values.73const CPUFREQ_RELATION_E: u32 = 1 << 2;7475/// 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.81Low(bool),82/// Select the highest frequency below or at target.83High(bool),84/// Select the closest frequency to the target.85Close(bool),86}8788impl Relation {89// Construct from a C-compatible `u32` value.90fn new(val: u32) -> Result<Self> {91let efficient = val & CPUFREQ_RELATION_E != 0;9293Ok(match val & !CPUFREQ_RELATION_E {94CPUFREQ_RELATION_L => Self::Low(efficient),95CPUFREQ_RELATION_H => Self::High(efficient),96CPUFREQ_RELATION_C => Self::Close(efficient),97_ => return Err(EINVAL),98})99}100}101102impl From<Relation> for u32 {103// Convert to a C-compatible `u32` value.104fn from(rel: Relation) -> Self {105let (mut val, efficient) = match rel {106Relation::Low(e) => (CPUFREQ_RELATION_L, e),107Relation::High(e) => (CPUFREQ_RELATION_H, e),108Relation::Close(e) => (CPUFREQ_RELATION_C, e),109};110111if efficient {112val |= CPUFREQ_RELATION_E;113}114115val116}117}118119/// Policy data.120///121/// Rust abstraction for the C `struct cpufreq_policy_data`.122///123/// # Invariants124///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 remains128/// valid for the lifetime of the returned reference.129#[repr(transparent)]130pub struct PolicyData(Opaque<bindings::cpufreq_policy_data>);131132impl PolicyData {133/// Creates a mutable reference to an existing `struct cpufreq_policy_data` pointer.134///135/// # Safety136///137/// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime138/// of the returned reference.139#[inline]140pub 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 the144// lifetime of the returned reference.145unsafe { &mut *ptr.cast() }146}147148/// Returns a raw pointer to the underlying C `cpufreq_policy_data`.149#[inline]150pub fn as_raw(&self) -> *mut bindings::cpufreq_policy_data {151let this: *const Self = self;152this.cast_mut().cast()153}154155/// Wrapper for `cpufreq_generic_frequency_table_verify`.156#[inline]157pub fn generic_verify(&self) -> Result {158// SAFETY: By the type invariant, the pointer stored in `self` is valid.159to_result(unsafe { bindings::cpufreq_generic_frequency_table_verify(self.as_raw()) })160}161}162163/// The frequency table index.164///165/// Represents index with a frequency table.166///167/// # Invariants168///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);172173impl TableIndex {174/// Creates an instance of [`TableIndex`].175///176/// # Safety177///178/// The caller must ensure that `index` correspond to a valid entry in the [`Table`] it is used179/// for.180pub unsafe fn new(index: usize) -> Self {181// INVARIANT: The caller ensures that `index` correspond to a valid entry in the [`Table`].182Self(index)183}184}185186impl From<TableIndex> for usize {187#[inline]188fn from(index: TableIndex) -> Self {189index.0190}191}192193/// CPU frequency table.194///195/// Rust abstraction for the C `struct cpufreq_frequency_table`.196///197/// # Invariants198///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 and202/// remains valid for the lifetime of the returned reference.203///204/// # Examples205///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>);225226impl Table {227/// Creates a reference to an existing C `struct cpufreq_frequency_table` pointer.228///229/// # Safety230///231/// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime232/// of the returned reference.233#[inline]234pub 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 the238// lifetime of the returned reference.239unsafe { &*ptr.cast() }240}241242/// Returns the raw mutable pointer to the C `struct cpufreq_frequency_table`.243#[inline]244pub fn as_raw(&self) -> *mut bindings::cpufreq_frequency_table {245let this: *const Self = self;246this.cast_mut().cast()247}248249/// Returns frequency at `index` in the [`Table`].250#[inline]251pub fn freq(&self, index: TableIndex) -> Result<Hertz> {252// SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is253// guaranteed to be valid by its safety requirements.254Ok(Hertz::from_khz(unsafe {255(*self.as_raw().add(index.into())).frequency.try_into()?256}))257}258259/// Returns flags at `index` in the [`Table`].260#[inline]261pub fn flags(&self, index: TableIndex) -> u32 {262// SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is263// guaranteed to be valid by its safety requirements.264unsafe { (*self.as_raw().add(index.into())).flags }265}266267/// Returns data at `index` in the [`Table`].268#[inline]269pub fn data(&self, index: TableIndex) -> u32 {270// SAFETY: By the type invariant, the pointer stored in `self` is valid and `index` is271// guaranteed to be valid by its safety requirements.272unsafe { (*self.as_raw().add(index.into())).driver_data }273}274}275276/// CPU frequency table owned and pinned in memory, created from a [`TableBuilder`].277pub struct TableBox {278entries: Pin<KVec<bindings::cpufreq_frequency_table>>,279}280281impl TableBox {282/// Constructs a new [`TableBox`] from a [`KVec`] of entries.283///284/// # Errors285///286/// Returns `EINVAL` if the entries list is empty.287#[inline]288fn new(entries: KVec<bindings::cpufreq_frequency_table>) -> Result<Self> {289if entries.is_empty() {290return Err(EINVAL);291}292293Ok(Self {294// Pin the entries to memory, since we are passing its pointer to the C code.295entries: Pin::new(entries),296})297}298299/// Returns a raw pointer to the underlying C `cpufreq_frequency_table`.300#[inline]301fn as_raw(&self) -> *const bindings::cpufreq_frequency_table {302// The pointer is valid until the table gets dropped.303self.entries.as_ptr()304}305}306307impl Deref for TableBox {308type Target = Table;309310fn deref(&self) -> &Self::Target {311// SAFETY: The caller owns TableBox, it is safe to deref.312unsafe { Self::Target::from_raw(self.as_raw()) }313}314}315316/// CPU frequency table builder.317///318/// This is used by the CPU frequency drivers to build a frequency table dynamically.319///320/// # Examples321///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 {352entries: KVec<bindings::cpufreq_frequency_table>,353}354355impl TableBuilder {356/// Creates a new instance of [`TableBuilder`].357#[inline]358pub fn new() -> Self {359Self {360entries: KVec::new(),361}362}363364/// Adds a new entry to the table.365pub fn add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result {366// Adds the new entry at the end of the vector.367Ok(self.entries.push(368bindings::cpufreq_frequency_table {369flags,370driver_data,371frequency: freq.as_khz() as u32,372},373GFP_KERNEL,374)?)375}376377/// Consumes the [`TableBuilder`] and returns [`TableBox`].378pub fn to_table(mut self) -> Result<TableBox> {379// Add last entry to the table.380self.add(Hertz(c_ulong::MAX), 0, 0)?;381382TableBox::new(self.entries)383}384}385386/// CPU frequency policy.387///388/// Rust abstraction for the C `struct cpufreq_policy`.389///390/// # Invariants391///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 valid395/// for the lifetime of the returned reference.396///397/// # Examples398///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/// policy406/// .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>);415416impl Policy {417/// Creates a reference to an existing `struct cpufreq_policy` pointer.418///419/// # Safety420///421/// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime422/// of the returned reference.423#[inline]424pub 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 the428// lifetime of the returned reference.429unsafe { &*ptr.cast() }430}431432/// Creates a mutable reference to an existing `struct cpufreq_policy` pointer.433///434/// # Safety435///436/// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime437/// of the returned reference.438#[inline]439pub 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 the443// lifetime of the returned reference.444unsafe { &mut *ptr.cast() }445}446447/// Returns a raw mutable pointer to the C `struct cpufreq_policy`.448#[inline]449fn as_raw(&self) -> *mut bindings::cpufreq_policy {450let this: *const Self = self;451this.cast_mut().cast()452}453454#[inline]455fn as_ref(&self) -> &bindings::cpufreq_policy {456// SAFETY: By the type invariant, the pointer stored in `self` is valid.457unsafe { &*self.as_raw() }458}459460#[inline]461fn as_mut_ref(&mut self) -> &mut bindings::cpufreq_policy {462// SAFETY: By the type invariant, the pointer stored in `self` is valid.463unsafe { &mut *self.as_raw() }464}465466/// Returns the primary CPU for the [`Policy`].467#[inline]468pub fn cpu(&self) -> CpuId {469// SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.470unsafe { CpuId::from_u32_unchecked(self.as_ref().cpu) }471}472473/// Returns the minimum frequency for the [`Policy`].474#[inline]475pub fn min(&self) -> Hertz {476Hertz::from_khz(self.as_ref().min as usize)477}478479/// Set the minimum frequency for the [`Policy`].480#[inline]481pub fn set_min(&mut self, min: Hertz) -> &mut Self {482self.as_mut_ref().min = min.as_khz() as u32;483self484}485486/// Returns the maximum frequency for the [`Policy`].487#[inline]488pub fn max(&self) -> Hertz {489Hertz::from_khz(self.as_ref().max as usize)490}491492/// Set the maximum frequency for the [`Policy`].493#[inline]494pub fn set_max(&mut self, max: Hertz) -> &mut Self {495self.as_mut_ref().max = max.as_khz() as u32;496self497}498499/// Returns the current frequency for the [`Policy`].500#[inline]501pub fn cur(&self) -> Hertz {502Hertz::from_khz(self.as_ref().cur as usize)503}504505/// Returns the suspend frequency for the [`Policy`].506#[inline]507pub fn suspend_freq(&self) -> Hertz {508Hertz::from_khz(self.as_ref().suspend_freq as usize)509}510511/// Sets the suspend frequency for the [`Policy`].512#[inline]513pub fn set_suspend_freq(&mut self, freq: Hertz) -> &mut Self {514self.as_mut_ref().suspend_freq = freq.as_khz() as u32;515self516}517518/// Provides a wrapper to the generic suspend routine.519#[inline]520pub fn generic_suspend(&mut self) -> Result {521// SAFETY: By the type invariant, the pointer stored in `self` is valid.522to_result(unsafe { bindings::cpufreq_generic_suspend(self.as_mut_ref()) })523}524525/// Provides a wrapper to the generic get routine.526#[inline]527pub fn generic_get(&self) -> Result<u32> {528// SAFETY: By the type invariant, the pointer stored in `self` is valid.529Ok(unsafe { bindings::cpufreq_generic_get(u32::from(self.cpu())) })530}531532/// Provides a wrapper to the register with energy model using the OPP core.533#[cfg(CONFIG_PM_OPP)]534#[inline]535pub fn register_em_opp(&mut self) {536// SAFETY: By the type invariant, the pointer stored in `self` is valid.537unsafe { bindings::cpufreq_register_em_with_opp(self.as_mut_ref()) };538}539540/// Gets [`cpumask::Cpumask`] for a cpufreq [`Policy`].541#[inline]542pub fn cpus(&mut self) -> &mut cpumask::Cpumask {543// SAFETY: The pointer to `cpus` is valid for writing and remains valid for the lifetime of544// the returned reference.545unsafe { cpumask::CpumaskVar::from_raw_mut(&mut self.as_mut_ref().cpus) }546}547548/// Sets clock for the [`Policy`].549///550/// # Safety551///552/// The caller must guarantee that the returned [`Clk`] is not dropped while it is getting used553/// by the C code.554#[cfg(CONFIG_COMMON_CLK)]555pub unsafe fn set_clk(&mut self, dev: &Device, name: Option<&CStr>) -> Result<Clk> {556let clk = Clk::get(dev, name)?;557self.as_mut_ref().clk = clk.as_raw();558Ok(clk)559}560561/// Allows / disallows frequency switching code to run on any CPU.562#[inline]563pub fn set_dvfs_possible_from_any_cpu(&mut self, val: bool) -> &mut Self {564self.as_mut_ref().dvfs_possible_from_any_cpu = val;565self566}567568/// Returns if fast switching of frequencies is possible or not.569#[inline]570pub fn fast_switch_possible(&self) -> bool {571self.as_ref().fast_switch_possible572}573574/// Enables / disables fast frequency switching.575#[inline]576pub fn set_fast_switch_possible(&mut self, val: bool) -> &mut Self {577self.as_mut_ref().fast_switch_possible = val;578self579}580581/// Sets transition latency (in nanoseconds) for the [`Policy`].582#[inline]583pub fn set_transition_latency_ns(&mut self, latency_ns: u32) -> &mut Self {584self.as_mut_ref().cpuinfo.transition_latency = latency_ns;585self586}587588/// Sets cpuinfo `min_freq`.589#[inline]590pub fn set_cpuinfo_min_freq(&mut self, min_freq: Hertz) -> &mut Self {591self.as_mut_ref().cpuinfo.min_freq = min_freq.as_khz() as u32;592self593}594595/// Sets cpuinfo `max_freq`.596#[inline]597pub fn set_cpuinfo_max_freq(&mut self, max_freq: Hertz) -> &mut Self {598self.as_mut_ref().cpuinfo.max_freq = max_freq.as_khz() as u32;599self600}601602/// Set `transition_delay_us`, i.e. the minimum time between successive frequency change603/// requests.604#[inline]605pub fn set_transition_delay_us(&mut self, transition_delay_us: u32) -> &mut Self {606self.as_mut_ref().transition_delay_us = transition_delay_us;607self608}609610/// Returns reference to the CPU frequency [`Table`] for the [`Policy`].611pub fn freq_table(&self) -> Result<&Table> {612if self.as_ref().freq_table.is_null() {613return Err(EINVAL);614}615616// SAFETY: The `freq_table` is guaranteed to be valid for reading and remains valid for the617// lifetime of the returned reference.618Ok(unsafe { Table::from_raw(self.as_ref().freq_table) })619}620621/// Sets the CPU frequency [`Table`] for the [`Policy`].622///623/// # Safety624///625/// The caller must guarantee that the [`Table`] is not dropped while it is getting used by the626/// C code.627#[inline]628pub unsafe fn set_freq_table(&mut self, table: &Table) -> &mut Self {629self.as_mut_ref().freq_table = table.as_raw();630self631}632633/// Returns the [`Policy`]'s private data.634pub fn data<T: ForeignOwnable>(&mut self) -> Option<<T>::Borrowed<'_>> {635if self.as_ref().driver_data.is_null() {636None637} else {638// SAFETY: The data is earlier set from [`set_data`].639Some(unsafe { T::borrow(self.as_ref().driver_data.cast()) })640}641}642643/// Sets the private data of the [`Policy`] using a foreign-ownable wrapper.644///645/// # Errors646///647/// Returns `EBUSY` if private data is already set.648fn set_data<T: ForeignOwnable>(&mut self, data: T) -> Result {649if self.as_ref().driver_data.is_null() {650// Transfer the ownership of the data to the foreign interface.651self.as_mut_ref().driver_data = <T as ForeignOwnable>::into_foreign(data).cast();652Ok(())653} else {654Err(EBUSY)655}656}657658/// Clears and returns ownership of the private data.659fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> {660if self.as_ref().driver_data.is_null() {661None662} else {663let data = Some(664// SAFETY: The data is earlier set by us from [`set_data`]. It is safe to take665// back the ownership of the data from the foreign interface.666unsafe { <T as ForeignOwnable>::from_foreign(self.as_ref().driver_data.cast()) },667);668self.as_mut_ref().driver_data = ptr::null_mut();669data670}671}672}673674/// CPU frequency policy created from a CPU number.675///676/// This struct represents the CPU frequency policy obtained for a specific CPU, providing safe677/// access to the underlying `cpufreq_policy` and ensuring proper cleanup when the `PolicyCpu` is678/// dropped.679struct PolicyCpu<'a>(&'a mut Policy);680681impl<'a> PolicyCpu<'a> {682fn from_cpu(cpu: CpuId) -> Result<Self> {683// SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU.684let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) })?;685686Ok(Self(687// SAFETY: The `ptr` is guaranteed to be valid and remains valid for the lifetime of688// the returned reference.689unsafe { Policy::from_raw_mut(ptr) },690))691}692}693694impl<'a> Deref for PolicyCpu<'a> {695type Target = Policy;696697fn deref(&self) -> &Self::Target {698self.0699}700}701702impl<'a> DerefMut for PolicyCpu<'a> {703fn deref_mut(&mut self) -> &mut Policy {704self.0705}706}707708impl<'a> Drop for PolicyCpu<'a> {709fn drop(&mut self) {710// SAFETY: The underlying pointer is guaranteed to be valid for the lifetime of `self`.711unsafe { bindings::cpufreq_cpu_put(self.0.as_raw()) };712}713}714715/// 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.723const NAME: &'static CStr;724725/// Driver's flags.726const FLAGS: u16;727728/// Boost support.729const BOOST_ENABLED: bool;730731/// Policy specific data.732///733/// Require that `PData` implements `ForeignOwnable`. We guarantee to never move the underlying734/// wrapped data structure.735type PData: ForeignOwnable;736737/// Driver's `init` callback.738fn init(policy: &mut Policy) -> Result<Self::PData>;739740/// Driver's `exit` callback.741fn exit(_policy: &mut Policy, _data: Option<Self::PData>) -> Result {742build_error!(VTABLE_DEFAULT_ERROR)743}744745/// Driver's `online` callback.746fn online(_policy: &mut Policy) -> Result {747build_error!(VTABLE_DEFAULT_ERROR)748}749750/// Driver's `offline` callback.751fn offline(_policy: &mut Policy) -> Result {752build_error!(VTABLE_DEFAULT_ERROR)753}754755/// Driver's `suspend` callback.756fn suspend(_policy: &mut Policy) -> Result {757build_error!(VTABLE_DEFAULT_ERROR)758}759760/// Driver's `resume` callback.761fn resume(_policy: &mut Policy) -> Result {762build_error!(VTABLE_DEFAULT_ERROR)763}764765/// Driver's `ready` callback.766fn ready(_policy: &mut Policy) {767build_error!(VTABLE_DEFAULT_ERROR)768}769770/// Driver's `verify` callback.771fn verify(data: &mut PolicyData) -> Result;772773/// Driver's `setpolicy` callback.774fn setpolicy(_policy: &mut Policy) -> Result {775build_error!(VTABLE_DEFAULT_ERROR)776}777778/// Driver's `target` callback.779fn target(_policy: &mut Policy, _target_freq: u32, _relation: Relation) -> Result {780build_error!(VTABLE_DEFAULT_ERROR)781}782783/// Driver's `target_index` callback.784fn target_index(_policy: &mut Policy, _index: TableIndex) -> Result {785build_error!(VTABLE_DEFAULT_ERROR)786}787788/// Driver's `fast_switch` callback.789fn fast_switch(_policy: &mut Policy, _target_freq: u32) -> u32 {790build_error!(VTABLE_DEFAULT_ERROR)791}792793/// Driver's `adjust_perf` callback.794fn adjust_perf(_policy: &mut Policy, _min_perf: usize, _target_perf: usize, _capacity: usize) {795build_error!(VTABLE_DEFAULT_ERROR)796}797798/// Driver's `get_intermediate` callback.799fn get_intermediate(_policy: &mut Policy, _index: TableIndex) -> u32 {800build_error!(VTABLE_DEFAULT_ERROR)801}802803/// Driver's `target_intermediate` callback.804fn target_intermediate(_policy: &mut Policy, _index: TableIndex) -> Result {805build_error!(VTABLE_DEFAULT_ERROR)806}807808/// Driver's `get` callback.809fn get(_policy: &mut Policy) -> Result<u32> {810build_error!(VTABLE_DEFAULT_ERROR)811}812813/// Driver's `update_limits` callback.814fn update_limits(_policy: &mut Policy) {815build_error!(VTABLE_DEFAULT_ERROR)816}817818/// Driver's `bios_limit` callback.819fn bios_limit(_policy: &mut Policy, _limit: &mut u32) -> Result {820build_error!(VTABLE_DEFAULT_ERROR)821}822823/// Driver's `set_boost` callback.824fn set_boost(_policy: &mut Policy, _state: i32) -> Result {825build_error!(VTABLE_DEFAULT_ERROR)826}827828/// Driver's `register_em` callback.829fn register_em(_policy: &mut Policy) {830build_error!(VTABLE_DEFAULT_ERROR)831}832}833834/// CPU frequency driver Registration.835///836/// # Examples837///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 here864/// 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 frequency881/// 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/// ) -> Result<Pin<KBox<Self>>> {897/// cpufreq::Registration::<SampleDriver>::new_foreign_owned(pdev.as_ref())?;898/// Ok(KBox::new(Self {}, GFP_KERNEL)?.into())899/// }900/// }901/// ```902#[repr(transparent)]903pub struct Registration<T: Driver>(KBox<UnsafeCell<bindings::cpufreq_driver>>, PhantomData<T>);904905/// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between threads906/// or CPUs, so it is safe to share it.907unsafe impl<T: Driver> Sync for Registration<T> {}908909#[allow(clippy::non_send_fields_in_send_ty)]910/// SAFETY: Registration with and unregistration from the cpufreq subsystem can happen from any911/// thread.912unsafe impl<T: Driver> Send for Registration<T> {}913914impl<T: Driver> Registration<T> {915const VTABLE: bindings::cpufreq_driver = bindings::cpufreq_driver {916name: Self::copy_name(T::NAME),917boost_enabled: T::BOOST_ENABLED,918flags: T::FLAGS,919920// Initialize mandatory callbacks.921init: Some(Self::init_callback),922verify: Some(Self::verify_callback),923924// Initialize optional callbacks based on the traits of `T`.925setpolicy: if T::HAS_SETPOLICY {926Some(Self::setpolicy_callback)927} else {928None929},930target: if T::HAS_TARGET {931Some(Self::target_callback)932} else {933None934},935target_index: if T::HAS_TARGET_INDEX {936Some(Self::target_index_callback)937} else {938None939},940fast_switch: if T::HAS_FAST_SWITCH {941Some(Self::fast_switch_callback)942} else {943None944},945adjust_perf: if T::HAS_ADJUST_PERF {946Some(Self::adjust_perf_callback)947} else {948None949},950get_intermediate: if T::HAS_GET_INTERMEDIATE {951Some(Self::get_intermediate_callback)952} else {953None954},955target_intermediate: if T::HAS_TARGET_INTERMEDIATE {956Some(Self::target_intermediate_callback)957} else {958None959},960get: if T::HAS_GET {961Some(Self::get_callback)962} else {963None964},965update_limits: if T::HAS_UPDATE_LIMITS {966Some(Self::update_limits_callback)967} else {968None969},970bios_limit: if T::HAS_BIOS_LIMIT {971Some(Self::bios_limit_callback)972} else {973None974},975online: if T::HAS_ONLINE {976Some(Self::online_callback)977} else {978None979},980offline: if T::HAS_OFFLINE {981Some(Self::offline_callback)982} else {983None984},985exit: if T::HAS_EXIT {986Some(Self::exit_callback)987} else {988None989},990suspend: if T::HAS_SUSPEND {991Some(Self::suspend_callback)992} else {993None994},995resume: if T::HAS_RESUME {996Some(Self::resume_callback)997} else {998None999},1000ready: if T::HAS_READY {1001Some(Self::ready_callback)1002} else {1003None1004},1005set_boost: if T::HAS_SET_BOOST {1006Some(Self::set_boost_callback)1007} else {1008None1009},1010register_em: if T::HAS_REGISTER_EM {1011Some(Self::register_em_callback)1012} else {1013None1014},1015..pin_init::zeroed()1016};10171018const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] {1019let src = name.to_bytes_with_nul();1020let mut dst = [0; CPUFREQ_NAME_LEN];10211022build_assert!(src.len() <= CPUFREQ_NAME_LEN);10231024let mut i = 0;1025while i < src.len() {1026dst[i] = src[i];1027i += 1;1028}10291030dst1031}10321033/// Registers a CPU frequency driver with the cpufreq core.1034pub fn new() -> Result<Self> {1035// We can't use `&Self::VTABLE` directly because the cpufreq core modifies some fields in1036// the C `struct cpufreq_driver`, which requires a mutable reference.1037let mut drv = KBox::new(UnsafeCell::new(Self::VTABLE), GFP_KERNEL)?;10381039// SAFETY: `drv` is guaranteed to be valid for the lifetime of `Registration`.1040to_result(unsafe { bindings::cpufreq_register_driver(drv.get_mut()) })?;10411042Ok(Self(drv, PhantomData))1043}10441045/// Same as [`Registration::new`], but does not return a [`Registration`] instance.1046///1047/// Instead the [`Registration`] is owned by [`devres::register`] and will be dropped, once the1048/// device is detached.1049pub fn new_foreign_owned(dev: &Device<Bound>) -> Result1050where1051T: 'static,1052{1053devres::register(dev, Self::new()?, GFP_KERNEL)1054}1055}10561057/// CPU frequency driver callbacks.1058impl<T: Driver> Registration<T> {1059/// Driver's `init` callback.1060///1061/// # Safety1062///1063/// - This function may only be called from the cpufreq C infrastructure.1064/// - The pointer arguments must be valid pointers.1065unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1066from_result(|| {1067// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1068// lifetime of `policy`.1069let policy = unsafe { Policy::from_raw_mut(ptr) };10701071let data = T::init(policy)?;1072policy.set_data(data)?;1073Ok(0)1074})1075}10761077/// Driver's `exit` callback.1078///1079/// # Safety1080///1081/// - This function may only be called from the cpufreq C infrastructure.1082/// - The pointer arguments must be valid pointers.1083unsafe extern "C" fn exit_callback(ptr: *mut bindings::cpufreq_policy) {1084// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1085// lifetime of `policy`.1086let policy = unsafe { Policy::from_raw_mut(ptr) };10871088let data = policy.clear_data();1089let _ = T::exit(policy, data);1090}10911092/// Driver's `online` callback.1093///1094/// # Safety1095///1096/// - This function may only be called from the cpufreq C infrastructure.1097/// - The pointer arguments must be valid pointers.1098unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1099from_result(|| {1100// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1101// lifetime of `policy`.1102let policy = unsafe { Policy::from_raw_mut(ptr) };1103T::online(policy).map(|()| 0)1104})1105}11061107/// Driver's `offline` callback.1108///1109/// # Safety1110///1111/// - This function may only be called from the cpufreq C infrastructure.1112/// - The pointer arguments must be valid pointers.1113unsafe extern "C" fn offline_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1114from_result(|| {1115// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1116// lifetime of `policy`.1117let policy = unsafe { Policy::from_raw_mut(ptr) };1118T::offline(policy).map(|()| 0)1119})1120}11211122/// Driver's `suspend` callback.1123///1124/// # Safety1125///1126/// - This function may only be called from the cpufreq C infrastructure.1127/// - The pointer arguments must be valid pointers.1128unsafe extern "C" fn suspend_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1129from_result(|| {1130// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1131// lifetime of `policy`.1132let policy = unsafe { Policy::from_raw_mut(ptr) };1133T::suspend(policy).map(|()| 0)1134})1135}11361137/// Driver's `resume` callback.1138///1139/// # Safety1140///1141/// - This function may only be called from the cpufreq C infrastructure.1142/// - The pointer arguments must be valid pointers.1143unsafe extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1144from_result(|| {1145// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1146// lifetime of `policy`.1147let policy = unsafe { Policy::from_raw_mut(ptr) };1148T::resume(policy).map(|()| 0)1149})1150}11511152/// Driver's `ready` callback.1153///1154/// # Safety1155///1156/// - This function may only be called from the cpufreq C infrastructure.1157/// - The pointer arguments must be valid pointers.1158unsafe extern "C" fn ready_callback(ptr: *mut bindings::cpufreq_policy) {1159// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1160// lifetime of `policy`.1161let policy = unsafe { Policy::from_raw_mut(ptr) };1162T::ready(policy);1163}11641165/// Driver's `verify` callback.1166///1167/// # Safety1168///1169/// - This function may only be called from the cpufreq C infrastructure.1170/// - The pointer arguments must be valid pointers.1171unsafe extern "C" fn verify_callback(ptr: *mut bindings::cpufreq_policy_data) -> c_int {1172from_result(|| {1173// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1174// lifetime of `policy`.1175let data = unsafe { PolicyData::from_raw_mut(ptr) };1176T::verify(data).map(|()| 0)1177})1178}11791180/// Driver's `setpolicy` callback.1181///1182/// # Safety1183///1184/// - This function may only be called from the cpufreq C infrastructure.1185/// - The pointer arguments must be valid pointers.1186unsafe extern "C" fn setpolicy_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {1187from_result(|| {1188// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1189// lifetime of `policy`.1190let policy = unsafe { Policy::from_raw_mut(ptr) };1191T::setpolicy(policy).map(|()| 0)1192})1193}11941195/// Driver's `target` callback.1196///1197/// # Safety1198///1199/// - This function may only be called from the cpufreq C infrastructure.1200/// - The pointer arguments must be valid pointers.1201unsafe extern "C" fn target_callback(1202ptr: *mut bindings::cpufreq_policy,1203target_freq: c_uint,1204relation: c_uint,1205) -> c_int {1206from_result(|| {1207// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1208// lifetime of `policy`.1209let policy = unsafe { Policy::from_raw_mut(ptr) };1210T::target(policy, target_freq, Relation::new(relation)?).map(|()| 0)1211})1212}12131214/// Driver's `target_index` callback.1215///1216/// # Safety1217///1218/// - This function may only be called from the cpufreq C infrastructure.1219/// - The pointer arguments must be valid pointers.1220unsafe extern "C" fn target_index_callback(1221ptr: *mut bindings::cpufreq_policy,1222index: c_uint,1223) -> c_int {1224from_result(|| {1225// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1226// lifetime of `policy`.1227let policy = unsafe { Policy::from_raw_mut(ptr) };12281229// SAFETY: The C code guarantees that `index` corresponds to a valid entry in the1230// frequency table.1231let index = unsafe { TableIndex::new(index as usize) };12321233T::target_index(policy, index).map(|()| 0)1234})1235}12361237/// Driver's `fast_switch` callback.1238///1239/// # Safety1240///1241/// - This function may only be called from the cpufreq C infrastructure.1242/// - The pointer arguments must be valid pointers.1243unsafe extern "C" fn fast_switch_callback(1244ptr: *mut bindings::cpufreq_policy,1245target_freq: c_uint,1246) -> c_uint {1247// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1248// lifetime of `policy`.1249let policy = unsafe { Policy::from_raw_mut(ptr) };1250T::fast_switch(policy, target_freq)1251}12521253/// Driver's `adjust_perf` callback.1254///1255/// # Safety1256///1257/// - This function may only be called from the cpufreq C infrastructure.1258unsafe extern "C" fn adjust_perf_callback(1259cpu: c_uint,1260min_perf: c_ulong,1261target_perf: c_ulong,1262capacity: c_ulong,1263) {1264// SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.1265let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };12661267if let Ok(mut policy) = PolicyCpu::from_cpu(cpu_id) {1268T::adjust_perf(&mut policy, min_perf, target_perf, capacity);1269}1270}12711272/// Driver's `get_intermediate` callback.1273///1274/// # Safety1275///1276/// - This function may only be called from the cpufreq C infrastructure.1277/// - The pointer arguments must be valid pointers.1278unsafe extern "C" fn get_intermediate_callback(1279ptr: *mut bindings::cpufreq_policy,1280index: c_uint,1281) -> c_uint {1282// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1283// lifetime of `policy`.1284let policy = unsafe { Policy::from_raw_mut(ptr) };12851286// SAFETY: The C code guarantees that `index` corresponds to a valid entry in the1287// frequency table.1288let index = unsafe { TableIndex::new(index as usize) };12891290T::get_intermediate(policy, index)1291}12921293/// Driver's `target_intermediate` callback.1294///1295/// # Safety1296///1297/// - This function may only be called from the cpufreq C infrastructure.1298/// - The pointer arguments must be valid pointers.1299unsafe extern "C" fn target_intermediate_callback(1300ptr: *mut bindings::cpufreq_policy,1301index: c_uint,1302) -> c_int {1303from_result(|| {1304// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1305// lifetime of `policy`.1306let policy = unsafe { Policy::from_raw_mut(ptr) };13071308// SAFETY: The C code guarantees that `index` corresponds to a valid entry in the1309// frequency table.1310let index = unsafe { TableIndex::new(index as usize) };13111312T::target_intermediate(policy, index).map(|()| 0)1313})1314}13151316/// Driver's `get` callback.1317///1318/// # Safety1319///1320/// - This function may only be called from the cpufreq C infrastructure.1321unsafe extern "C" fn get_callback(cpu: c_uint) -> c_uint {1322// SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.1323let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };13241325PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))1326}13271328/// Driver's `update_limit` callback.1329///1330/// # Safety1331///1332/// - This function may only be called from the cpufreq C infrastructure.1333/// - The pointer arguments must be valid pointers.1334unsafe extern "C" fn update_limits_callback(ptr: *mut bindings::cpufreq_policy) {1335// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1336// lifetime of `policy`.1337let policy = unsafe { Policy::from_raw_mut(ptr) };1338T::update_limits(policy);1339}13401341/// Driver's `bios_limit` callback.1342///1343/// # Safety1344///1345/// - This function may only be called from the cpufreq C infrastructure.1346/// - The pointer arguments must be valid pointers.1347unsafe extern "C" fn bios_limit_callback(cpu: c_int, limit: *mut c_uint) -> c_int {1348// SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.1349let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) };13501351from_result(|| {1352let mut policy = PolicyCpu::from_cpu(cpu_id)?;13531354// SAFETY: `limit` is guaranteed by the C code to be valid.1355T::bios_limit(&mut policy, &mut (unsafe { *limit })).map(|()| 0)1356})1357}13581359/// Driver's `set_boost` callback.1360///1361/// # Safety1362///1363/// - This function may only be called from the cpufreq C infrastructure.1364/// - The pointer arguments must be valid pointers.1365unsafe extern "C" fn set_boost_callback(1366ptr: *mut bindings::cpufreq_policy,1367state: c_int,1368) -> c_int {1369from_result(|| {1370// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1371// lifetime of `policy`.1372let policy = unsafe { Policy::from_raw_mut(ptr) };1373T::set_boost(policy, state).map(|()| 0)1374})1375}13761377/// Driver's `register_em` callback.1378///1379/// # Safety1380///1381/// - This function may only be called from the cpufreq C infrastructure.1382/// - The pointer arguments must be valid pointers.1383unsafe extern "C" fn register_em_callback(ptr: *mut bindings::cpufreq_policy) {1384// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the1385// lifetime of `policy`.1386let policy = unsafe { Policy::from_raw_mut(ptr) };1387T::register_em(policy);1388}1389}13901391impl<T: Driver> Drop for Registration<T> {1392/// Unregisters with the cpufreq core.1393fn drop(&mut self) {1394// SAFETY: `self.0` is guaranteed to be valid for the lifetime of `Registration`.1395unsafe { bindings::cpufreq_unregister_driver(self.0.get_mut()) };1396}1397}139813991400