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