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