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