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 ops::{Deref, DerefMut}, 31 pin::Pin, 32 ptr, 33 }; 34 35 use macros::vtable; 36 37 /// Maximum length of CPU frequency driver's name. 38 const CPUFREQ_NAME_LEN: usize = bindings::CPUFREQ_NAME_LEN as usize; 39 40 /// Default transition latency value in nanoseconds. 41 pub const DEFAULT_TRANSITION_LATENCY_NS: u32 = bindings::CPUFREQ_DEFAULT_TRANSITION_LATENCY_NS; 42 43 /// CPU frequency driver flags. 44 pub 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. 68 const CPUFREQ_RELATION_L: u32 = 0; 69 const CPUFREQ_RELATION_H: u32 = 1; 70 const CPUFREQ_RELATION_C: u32 = 2; 71 72 /// Can be used with any of the above values. 73 const 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)] 79 pub 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 88 impl 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 102 impl 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)] 130 pub struct PolicyData(Opaque<bindings::cpufreq_policy_data>); 131 132 impl 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)] 171 pub struct TableIndex(usize); 172 173 impl 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 186 impl 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)] 224 pub struct Table(Opaque<bindings::cpufreq_frequency_table>); 225 226 impl 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`]. 277 pub struct TableBox { 278 entries: Pin<KVec<bindings::cpufreq_frequency_table>>, 279 } 280 281 impl 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 307 impl 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)] 351 pub struct TableBuilder { 352 entries: KVec<bindings::cpufreq_frequency_table>, 353 } 354 355 impl 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 raw frequency-table entry. 365 fn push(&mut self, frequency: u32, 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, 372 }, 373 GFP_KERNEL, 374 )?) 375 } 376 377 /// Adds a new entry to the table. 378 pub fn add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result { 379 self.push(freq.as_khz() as u32, flags, driver_data) 380 } 381 382 /// Consumes the [`TableBuilder`] and returns [`TableBox`]. 383 pub fn to_table(mut self) -> Result<TableBox> { 384 // Add last entry to the table. 385 self.push(bindings::CPUFREQ_TABLE_END as u32, 0, 0)?; 386 387 TableBox::new(self.entries) 388 } 389 } 390 391 /// CPU frequency policy. 392 /// 393 /// Rust abstraction for the C `struct cpufreq_policy`. 394 /// 395 /// # Invariants 396 /// 397 /// A [`Policy`] instance always corresponds to a valid C `struct cpufreq_policy`. 398 /// 399 /// The callers must ensure that the `struct cpufreq_policy` is valid for access and remains valid 400 /// for the lifetime of the returned reference. 401 /// 402 /// # Examples 403 /// 404 /// The following example demonstrates how to create a CPU frequency table. 405 /// 406 /// ``` 407 /// use kernel::cpufreq::{DEFAULT_TRANSITION_LATENCY_NS, Policy}; 408 /// 409 /// #[allow(clippy::double_parens, reason = "False positive before 1.92.0")] 410 /// fn update_policy(policy: &mut Policy) { 411 /// policy 412 /// .set_dvfs_possible_from_any_cpu(true) 413 /// .set_fast_switch_possible(true) 414 /// .set_transition_latency_ns(DEFAULT_TRANSITION_LATENCY_NS); 415 /// 416 /// pr_info!("The policy details are: {:?}\n", (policy.cpu(), policy.cur())); 417 /// } 418 /// ``` 419 #[repr(transparent)] 420 pub struct Policy(Opaque<bindings::cpufreq_policy>); 421 422 impl Policy { 423 /// Creates a reference to an existing `struct cpufreq_policy` pointer. 424 /// 425 /// # Safety 426 /// 427 /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime 428 /// of the returned reference. 429 #[inline] 430 pub unsafe fn from_raw<'a>(ptr: *const bindings::cpufreq_policy) -> &'a Self { 431 // SAFETY: Guaranteed by the safety requirements of the function. 432 // 433 // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the 434 // lifetime of the returned reference. 435 unsafe { &*ptr.cast() } 436 } 437 438 /// Creates a mutable reference to an existing `struct cpufreq_policy` pointer. 439 /// 440 /// # Safety 441 /// 442 /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime 443 /// of the returned reference. 444 #[inline] 445 pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy) -> &'a mut Self { 446 // SAFETY: Guaranteed by the safety requirements of the function. 447 // 448 // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the 449 // lifetime of the returned reference. 450 unsafe { &mut *ptr.cast() } 451 } 452 453 /// Returns a raw mutable pointer to the C `struct cpufreq_policy`. 454 #[inline] 455 fn as_raw(&self) -> *mut bindings::cpufreq_policy { 456 let this: *const Self = self; 457 this.cast_mut().cast() 458 } 459 460 #[inline] 461 fn as_ref(&self) -> &bindings::cpufreq_policy { 462 // SAFETY: By the type invariant, the pointer stored in `self` is valid. 463 unsafe { &*self.as_raw() } 464 } 465 466 #[inline] 467 fn as_mut_ref(&mut self) -> &mut bindings::cpufreq_policy { 468 // SAFETY: By the type invariant, the pointer stored in `self` is valid. 469 unsafe { &mut *self.as_raw() } 470 } 471 472 /// Returns the primary CPU for the [`Policy`]. 473 #[inline] 474 pub fn cpu(&self) -> CpuId { 475 // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number. 476 unsafe { CpuId::from_u32_unchecked(self.as_ref().cpu) } 477 } 478 479 /// Returns the minimum frequency for the [`Policy`]. 480 #[inline] 481 pub fn min(&self) -> Hertz { 482 Hertz::from_khz(self.as_ref().min as usize) 483 } 484 485 /// Set the minimum frequency for the [`Policy`]. 486 #[inline] 487 pub fn set_min(&mut self, min: Hertz) -> &mut Self { 488 self.as_mut_ref().min = min.as_khz() as u32; 489 self 490 } 491 492 /// Returns the maximum frequency for the [`Policy`]. 493 #[inline] 494 pub fn max(&self) -> Hertz { 495 Hertz::from_khz(self.as_ref().max as usize) 496 } 497 498 /// Set the maximum frequency for the [`Policy`]. 499 #[inline] 500 pub fn set_max(&mut self, max: Hertz) -> &mut Self { 501 self.as_mut_ref().max = max.as_khz() as u32; 502 self 503 } 504 505 /// Returns the current frequency for the [`Policy`]. 506 #[inline] 507 pub fn cur(&self) -> Hertz { 508 Hertz::from_khz(self.as_ref().cur as usize) 509 } 510 511 /// Returns the suspend frequency for the [`Policy`]. 512 #[inline] 513 pub fn suspend_freq(&self) -> Hertz { 514 Hertz::from_khz(self.as_ref().suspend_freq as usize) 515 } 516 517 /// Sets the suspend frequency for the [`Policy`]. 518 #[inline] 519 pub fn set_suspend_freq(&mut self, freq: Hertz) -> &mut Self { 520 self.as_mut_ref().suspend_freq = freq.as_khz() as u32; 521 self 522 } 523 524 /// Provides a wrapper to the generic suspend routine. 525 #[inline] 526 pub fn generic_suspend(&mut self) -> Result { 527 // SAFETY: By the type invariant, the pointer stored in `self` is valid. 528 to_result(unsafe { bindings::cpufreq_generic_suspend(self.as_mut_ref()) }) 529 } 530 531 /// Provides a wrapper to the generic get routine. 532 #[inline] 533 pub fn generic_get(&self) -> Result<u32> { 534 // SAFETY: By the type invariant, the pointer stored in `self` is valid. 535 Ok(unsafe { bindings::cpufreq_generic_get(u32::from(self.cpu())) }) 536 } 537 538 /// Provides a wrapper to the register with energy model using the OPP core. 539 #[cfg(CONFIG_PM_OPP)] 540 #[inline] 541 pub fn register_em_opp(&mut self) { 542 // SAFETY: By the type invariant, the pointer stored in `self` is valid. 543 unsafe { bindings::cpufreq_register_em_with_opp(self.as_mut_ref()) }; 544 } 545 546 /// Gets [`cpumask::Cpumask`] for a cpufreq [`Policy`]. 547 #[inline] 548 pub fn cpus(&mut self) -> &mut cpumask::Cpumask { 549 // SAFETY: The pointer to `cpus` is valid for writing and remains valid for the lifetime of 550 // the returned reference. 551 unsafe { cpumask::CpumaskVar::from_raw_mut(&mut self.as_mut_ref().cpus) } 552 } 553 554 /// Sets clock for the [`Policy`]. 555 /// 556 /// # Safety 557 /// 558 /// The caller must guarantee that the returned [`Clk`] is not dropped while it is getting used 559 /// by the C code. 560 #[cfg(CONFIG_COMMON_CLK)] 561 pub unsafe fn set_clk(&mut self, dev: &Device, name: Option<&CStr>) -> Result<Clk> { 562 let clk = Clk::get(dev, name)?; 563 self.as_mut_ref().clk = clk.as_raw(); 564 Ok(clk) 565 } 566 567 /// Allows / disallows frequency switching code to run on any CPU. 568 #[inline] 569 pub fn set_dvfs_possible_from_any_cpu(&mut self, val: bool) -> &mut Self { 570 self.as_mut_ref().dvfs_possible_from_any_cpu = val; 571 self 572 } 573 574 /// Returns if fast switching of frequencies is possible or not. 575 #[inline] 576 pub fn fast_switch_possible(&self) -> bool { 577 self.as_ref().fast_switch_possible 578 } 579 580 /// Enables / disables fast frequency switching. 581 #[inline] 582 pub fn set_fast_switch_possible(&mut self, val: bool) -> &mut Self { 583 self.as_mut_ref().fast_switch_possible = val; 584 self 585 } 586 587 /// Sets transition latency (in nanoseconds) for the [`Policy`]. 588 #[inline] 589 pub fn set_transition_latency_ns(&mut self, latency_ns: u32) -> &mut Self { 590 self.as_mut_ref().cpuinfo.transition_latency = latency_ns; 591 self 592 } 593 594 /// Sets cpuinfo `min_freq`. 595 #[inline] 596 pub fn set_cpuinfo_min_freq(&mut self, min_freq: Hertz) -> &mut Self { 597 self.as_mut_ref().cpuinfo.min_freq = min_freq.as_khz() as u32; 598 self 599 } 600 601 /// Sets cpuinfo `max_freq`. 602 #[inline] 603 pub fn set_cpuinfo_max_freq(&mut self, max_freq: Hertz) -> &mut Self { 604 self.as_mut_ref().cpuinfo.max_freq = max_freq.as_khz() as u32; 605 self 606 } 607 608 /// Set `transition_delay_us`, i.e. the minimum time between successive frequency change 609 /// requests. 610 #[inline] 611 pub fn set_transition_delay_us(&mut self, transition_delay_us: u32) -> &mut Self { 612 self.as_mut_ref().transition_delay_us = transition_delay_us; 613 self 614 } 615 616 /// Returns reference to the CPU frequency [`Table`] for the [`Policy`]. 617 pub fn freq_table(&self) -> Result<&Table> { 618 if self.as_ref().freq_table.is_null() { 619 return Err(EINVAL); 620 } 621 622 // SAFETY: The `freq_table` is guaranteed to be valid for reading and remains valid for the 623 // lifetime of the returned reference. 624 Ok(unsafe { Table::from_raw(self.as_ref().freq_table) }) 625 } 626 627 /// Sets the CPU frequency [`Table`] for the [`Policy`]. 628 /// 629 /// # Safety 630 /// 631 /// The caller must guarantee that the [`Table`] is not dropped while it is getting used by the 632 /// C code. 633 #[inline] 634 pub unsafe fn set_freq_table(&mut self, table: &Table) -> &mut Self { 635 self.as_mut_ref().freq_table = table.as_raw(); 636 self 637 } 638 639 /// Returns the [`Policy`]'s private data. 640 pub fn data<T: ForeignOwnable>(&mut self) -> Option<<T>::Borrowed<'_>> { 641 if self.as_ref().driver_data.is_null() { 642 None 643 } else { 644 // SAFETY: The data is earlier set from [`set_data`]. 645 Some(unsafe { T::borrow(self.as_ref().driver_data.cast()) }) 646 } 647 } 648 649 /// Sets the private data of the [`Policy`] using a foreign-ownable wrapper. 650 /// 651 /// # Errors 652 /// 653 /// Returns `EBUSY` if private data is already set. 654 fn set_data<T: ForeignOwnable>(&mut self, data: T) -> Result { 655 if self.as_ref().driver_data.is_null() { 656 // Transfer the ownership of the data to the foreign interface. 657 self.as_mut_ref().driver_data = <T as ForeignOwnable>::into_foreign(data).cast(); 658 Ok(()) 659 } else { 660 Err(EBUSY) 661 } 662 } 663 664 /// Clears and returns ownership of the private data. 665 fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> { 666 if self.as_ref().driver_data.is_null() { 667 None 668 } else { 669 let data = Some( 670 // SAFETY: The data is earlier set by us from [`set_data`]. It is safe to take 671 // back the ownership of the data from the foreign interface. 672 unsafe { <T as ForeignOwnable>::from_foreign(self.as_ref().driver_data.cast()) }, 673 ); 674 self.as_mut_ref().driver_data = ptr::null_mut(); 675 data 676 } 677 } 678 } 679 680 /// CPU frequency policy created from a CPU number. 681 /// 682 /// This struct represents the CPU frequency policy obtained for a specific CPU, providing safe 683 /// access to the underlying `cpufreq_policy` and ensuring proper cleanup when the `PolicyCpu` is 684 /// dropped. 685 struct PolicyCpu<'a>(&'a mut Policy); 686 687 impl<'a> PolicyCpu<'a> { 688 fn from_cpu(cpu: CpuId) -> Result<Self> { 689 // SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU. 690 let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) })?; 691 692 Ok(Self( 693 // SAFETY: The `ptr` is guaranteed to be valid and remains valid for the lifetime of 694 // the returned reference. 695 unsafe { Policy::from_raw_mut(ptr) }, 696 )) 697 } 698 } 699 700 impl<'a> Deref for PolicyCpu<'a> { 701 type Target = Policy; 702 703 fn deref(&self) -> &Self::Target { 704 self.0 705 } 706 } 707 708 impl<'a> DerefMut for PolicyCpu<'a> { 709 fn deref_mut(&mut self) -> &mut Policy { 710 self.0 711 } 712 } 713 714 impl<'a> Drop for PolicyCpu<'a> { 715 fn drop(&mut self) { 716 // SAFETY: The underlying pointer is guaranteed to be valid for the lifetime of `self`. 717 unsafe { bindings::cpufreq_cpu_put(self.0.as_raw()) }; 718 } 719 } 720 721 /// CPU frequency driver. 722 /// 723 /// Implement this trait to provide a CPU frequency driver and its callbacks. 724 /// 725 /// Reference: <https://docs.kernel.org/cpu-freq/cpu-drivers.html> 726 #[vtable] 727 pub trait Driver { 728 /// Driver's name. 729 const NAME: &'static CStr; 730 731 /// Driver's flags. 732 const FLAGS: u16; 733 734 /// Boost support. 735 const BOOST_ENABLED: bool; 736 737 /// Policy specific data. 738 /// 739 /// Require that `PData` implements `ForeignOwnable`. We guarantee to never move the underlying 740 /// wrapped data structure. 741 type PData: ForeignOwnable; 742 743 /// Driver's `init` callback. 744 fn init(policy: &mut Policy) -> Result<Self::PData>; 745 746 /// Driver's `exit` callback. 747 fn exit(_policy: &mut Policy, _data: Option<Self::PData>) -> Result { 748 build_error!(VTABLE_DEFAULT_ERROR) 749 } 750 751 /// Driver's `online` callback. 752 fn online(_policy: &mut Policy) -> Result { 753 build_error!(VTABLE_DEFAULT_ERROR) 754 } 755 756 /// Driver's `offline` callback. 757 fn offline(_policy: &mut Policy) -> Result { 758 build_error!(VTABLE_DEFAULT_ERROR) 759 } 760 761 /// Driver's `suspend` callback. 762 fn suspend(_policy: &mut Policy) -> Result { 763 build_error!(VTABLE_DEFAULT_ERROR) 764 } 765 766 /// Driver's `resume` callback. 767 fn resume(_policy: &mut Policy) -> Result { 768 build_error!(VTABLE_DEFAULT_ERROR) 769 } 770 771 /// Driver's `ready` callback. 772 fn ready(_policy: &mut Policy) { 773 build_error!(VTABLE_DEFAULT_ERROR) 774 } 775 776 /// Driver's `verify` callback. 777 fn verify(data: &mut PolicyData) -> Result; 778 779 /// Driver's `setpolicy` callback. 780 fn setpolicy(_policy: &mut Policy) -> Result { 781 build_error!(VTABLE_DEFAULT_ERROR) 782 } 783 784 /// Driver's `target` callback. 785 fn target(_policy: &mut Policy, _target_freq: u32, _relation: Relation) -> Result { 786 build_error!(VTABLE_DEFAULT_ERROR) 787 } 788 789 /// Driver's `target_index` callback. 790 fn target_index(_policy: &mut Policy, _index: TableIndex) -> Result { 791 build_error!(VTABLE_DEFAULT_ERROR) 792 } 793 794 /// Driver's `fast_switch` callback. 795 fn fast_switch(_policy: &mut Policy, _target_freq: u32) -> u32 { 796 build_error!(VTABLE_DEFAULT_ERROR) 797 } 798 799 /// Driver's `adjust_perf` callback. 800 fn adjust_perf( 801 _policy: &mut Policy, 802 _min_perf: usize, 803 _target_perf: usize, 804 _max_perf: usize, 805 _capacity: usize, 806 ) { 807 build_error!(VTABLE_DEFAULT_ERROR) 808 } 809 810 /// Driver's `get_intermediate` callback. 811 fn get_intermediate(_policy: &mut Policy, _index: TableIndex) -> u32 { 812 build_error!(VTABLE_DEFAULT_ERROR) 813 } 814 815 /// Driver's `target_intermediate` callback. 816 fn target_intermediate(_policy: &mut Policy, _index: TableIndex) -> Result { 817 build_error!(VTABLE_DEFAULT_ERROR) 818 } 819 820 /// Driver's `get` callback. 821 fn get(_policy: &mut Policy) -> Result<u32> { 822 build_error!(VTABLE_DEFAULT_ERROR) 823 } 824 825 /// Driver's `update_limits` callback. 826 fn update_limits(_policy: &mut Policy) { 827 build_error!(VTABLE_DEFAULT_ERROR) 828 } 829 830 /// Driver's `bios_limit` callback. 831 /// 832 /// Returns HW/BIOS max frequency limitations for the CPU. 833 fn bios_limit(_policy: &mut Policy) -> Result<u32> { 834 build_error!(VTABLE_DEFAULT_ERROR) 835 } 836 837 /// Driver's `set_boost` callback. 838 fn set_boost(_policy: &mut Policy, _state: i32) -> Result { 839 build_error!(VTABLE_DEFAULT_ERROR) 840 } 841 842 /// Driver's `register_em` callback. 843 fn register_em(_policy: &mut Policy) { 844 build_error!(VTABLE_DEFAULT_ERROR) 845 } 846 } 847 848 /// CPU frequency driver Registration. 849 /// 850 /// # Examples 851 /// 852 /// The following example demonstrates how to register a cpufreq driver. 853 /// 854 /// ``` 855 /// use kernel::{ 856 /// cpufreq, 857 /// device::{Core, Device}, 858 /// macros::vtable, 859 /// of, platform, 860 /// sync::Arc, 861 /// }; 862 /// struct SampleDevice; 863 /// 864 /// #[derive(Default)] 865 /// struct SampleDriver; 866 /// 867 /// #[vtable] 868 /// impl cpufreq::Driver for SampleDriver { 869 /// const NAME: &'static CStr = c"cpufreq-sample"; 870 /// const FLAGS: u16 = cpufreq::flags::NEED_INITIAL_FREQ_CHECK | cpufreq::flags::IS_COOLING_DEV; 871 /// const BOOST_ENABLED: bool = true; 872 /// 873 /// type PData = Arc<SampleDevice>; 874 /// 875 /// fn init(policy: &mut cpufreq::Policy) -> Result<Self::PData> { 876 /// // Initialize here 877 /// Ok(Arc::new(SampleDevice, GFP_KERNEL)?) 878 /// } 879 /// 880 /// fn exit(_policy: &mut cpufreq::Policy, _data: Option<Self::PData>) -> Result { 881 /// Ok(()) 882 /// } 883 /// 884 /// fn suspend(policy: &mut cpufreq::Policy) -> Result { 885 /// policy.generic_suspend() 886 /// } 887 /// 888 /// fn verify(data: &mut cpufreq::PolicyData) -> Result { 889 /// data.generic_verify() 890 /// } 891 /// 892 /// fn target_index(policy: &mut cpufreq::Policy, index: cpufreq::TableIndex) -> Result { 893 /// // Update CPU frequency 894 /// Ok(()) 895 /// } 896 /// 897 /// fn get(policy: &mut cpufreq::Policy) -> Result<u32> { 898 /// policy.generic_get() 899 /// } 900 /// } 901 /// 902 /// impl platform::Driver for SampleDriver { 903 /// type IdInfo = (); 904 /// type Data<'bound> = Self; 905 /// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None; 906 /// 907 /// fn probe<'bound>( 908 /// pdev: &'bound platform::Device<Core<'_>>, 909 /// _id_info: Option<&'bound Self::IdInfo>, 910 /// ) -> impl PinInit<Self, Error> + 'bound { 911 /// cpufreq::Registration::<SampleDriver>::new_foreign_owned(pdev.as_ref())?; 912 /// Ok(Self {}) 913 /// } 914 /// } 915 /// ``` 916 #[repr(transparent)] 917 pub struct Registration<T: Driver>(KBox<UnsafeCell<bindings::cpufreq_driver>>, PhantomData<T>); 918 919 /// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between threads 920 /// or CPUs, so it is safe to share it. 921 unsafe impl<T: Driver> Sync for Registration<T> {} 922 923 #[allow(clippy::non_send_fields_in_send_ty)] 924 /// SAFETY: Registration with and unregistration from the cpufreq subsystem can happen from any 925 /// thread. 926 unsafe impl<T: Driver> Send for Registration<T> {} 927 928 impl<T: Driver> Registration<T> { 929 const VTABLE: bindings::cpufreq_driver = bindings::cpufreq_driver { 930 name: Self::copy_name(T::NAME), 931 boost_enabled: T::BOOST_ENABLED, 932 flags: T::FLAGS, 933 934 // Initialize mandatory callbacks. 935 init: Some(Self::init_callback), 936 verify: Some(Self::verify_callback), 937 938 // Initialize optional callbacks based on the traits of `T`. 939 setpolicy: if T::HAS_SETPOLICY { 940 Some(Self::setpolicy_callback) 941 } else { 942 None 943 }, 944 target: if T::HAS_TARGET { 945 Some(Self::target_callback) 946 } else { 947 None 948 }, 949 target_index: if T::HAS_TARGET_INDEX { 950 Some(Self::target_index_callback) 951 } else { 952 None 953 }, 954 fast_switch: if T::HAS_FAST_SWITCH { 955 Some(Self::fast_switch_callback) 956 } else { 957 None 958 }, 959 adjust_perf: if T::HAS_ADJUST_PERF { 960 Some(Self::adjust_perf_callback) 961 } else { 962 None 963 }, 964 get_intermediate: if T::HAS_GET_INTERMEDIATE { 965 Some(Self::get_intermediate_callback) 966 } else { 967 None 968 }, 969 target_intermediate: if T::HAS_TARGET_INTERMEDIATE { 970 Some(Self::target_intermediate_callback) 971 } else { 972 None 973 }, 974 get: if T::HAS_GET { 975 Some(Self::get_callback) 976 } else { 977 None 978 }, 979 update_limits: if T::HAS_UPDATE_LIMITS { 980 Some(Self::update_limits_callback) 981 } else { 982 None 983 }, 984 bios_limit: if T::HAS_BIOS_LIMIT { 985 Some(Self::bios_limit_callback) 986 } else { 987 None 988 }, 989 online: if T::HAS_ONLINE { 990 Some(Self::online_callback) 991 } else { 992 None 993 }, 994 offline: if T::HAS_OFFLINE { 995 Some(Self::offline_callback) 996 } else { 997 None 998 }, 999 exit: if T::HAS_EXIT { 1000 Some(Self::exit_callback) 1001 } else { 1002 None 1003 }, 1004 suspend: if T::HAS_SUSPEND { 1005 Some(Self::suspend_callback) 1006 } else { 1007 None 1008 }, 1009 resume: if T::HAS_RESUME { 1010 Some(Self::resume_callback) 1011 } else { 1012 None 1013 }, 1014 ready: if T::HAS_READY { 1015 Some(Self::ready_callback) 1016 } else { 1017 None 1018 }, 1019 set_boost: if T::HAS_SET_BOOST { 1020 Some(Self::set_boost_callback) 1021 } else { 1022 None 1023 }, 1024 register_em: if T::HAS_REGISTER_EM { 1025 Some(Self::register_em_callback) 1026 } else { 1027 None 1028 }, 1029 ..pin_init::zeroed() 1030 }; 1031 1032 // Always inline to optimize out error path of `build_assert`. 1033 #[inline(always)] 1034 const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] { 1035 let src = name.to_bytes_with_nul(); 1036 let mut dst = [0; CPUFREQ_NAME_LEN]; 1037 1038 build_assert!(src.len() <= CPUFREQ_NAME_LEN); 1039 1040 let mut i = 0; 1041 while i < src.len() { 1042 dst[i] = src[i]; 1043 i += 1; 1044 } 1045 1046 dst 1047 } 1048 1049 /// Registers a CPU frequency driver with the cpufreq core. 1050 pub fn new() -> Result<Self> { 1051 // We can't use `&Self::VTABLE` directly because the cpufreq core modifies some fields in 1052 // the C `struct cpufreq_driver`, which requires a mutable reference. 1053 let mut drv = KBox::new(UnsafeCell::new(Self::VTABLE), GFP_KERNEL)?; 1054 1055 // SAFETY: `drv` is guaranteed to be valid for the lifetime of `Registration`. 1056 to_result(unsafe { bindings::cpufreq_register_driver(drv.get_mut()) })?; 1057 1058 Ok(Self(drv, PhantomData)) 1059 } 1060 1061 /// Same as [`Registration::new`], but does not return a [`Registration`] instance. 1062 /// 1063 /// Instead the [`Registration`] is owned by [`devres::register`] and will be dropped, once the 1064 /// device is detached. 1065 pub fn new_foreign_owned(dev: &Device<Bound>) -> Result 1066 where 1067 T: 'static, 1068 { 1069 devres::register(dev, Self::new()?, GFP_KERNEL) 1070 } 1071 } 1072 1073 /// CPU frequency driver callbacks. 1074 impl<T: Driver> Registration<T> { 1075 /// Driver's `init` callback. 1076 /// 1077 /// # Safety 1078 /// 1079 /// - This function may only be called from the cpufreq C infrastructure. 1080 /// - The pointer arguments must be valid pointers. 1081 unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> c_int { 1082 from_result(|| { 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 = T::init(policy)?; 1088 policy.set_data(data)?; 1089 Ok(0) 1090 }) 1091 } 1092 1093 /// Driver's `exit` callback. 1094 /// 1095 /// # Safety 1096 /// 1097 /// - This function may only be called from the cpufreq C infrastructure. 1098 /// - The pointer arguments must be valid pointers. 1099 unsafe extern "C" fn exit_callback(ptr: *mut bindings::cpufreq_policy) { 1100 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1101 // lifetime of `policy`. 1102 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1103 1104 let data = policy.clear_data(); 1105 let _ = T::exit(policy, data); 1106 } 1107 1108 /// Driver's `online` callback. 1109 /// 1110 /// # Safety 1111 /// 1112 /// - This function may only be called from the cpufreq C infrastructure. 1113 /// - The pointer arguments must be valid pointers. 1114 unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> 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::online(policy).map(|()| 0) 1120 }) 1121 } 1122 1123 /// Driver's `offline` 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. 1129 unsafe extern "C" fn offline_callback(ptr: *mut bindings::cpufreq_policy) -> c_int { 1130 from_result(|| { 1131 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1132 // lifetime of `policy`. 1133 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1134 T::offline(policy).map(|()| 0) 1135 }) 1136 } 1137 1138 /// Driver's `suspend` callback. 1139 /// 1140 /// # Safety 1141 /// 1142 /// - This function may only be called from the cpufreq C infrastructure. 1143 /// - The pointer arguments must be valid pointers. 1144 unsafe extern "C" fn suspend_callback(ptr: *mut bindings::cpufreq_policy) -> c_int { 1145 from_result(|| { 1146 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1147 // lifetime of `policy`. 1148 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1149 T::suspend(policy).map(|()| 0) 1150 }) 1151 } 1152 1153 /// Driver's `resume` callback. 1154 /// 1155 /// # Safety 1156 /// 1157 /// - This function may only be called from the cpufreq C infrastructure. 1158 /// - The pointer arguments must be valid pointers. 1159 unsafe extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> c_int { 1160 from_result(|| { 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::resume(policy).map(|()| 0) 1165 }) 1166 } 1167 1168 /// Driver's `ready` 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 ready_callback(ptr: *mut bindings::cpufreq_policy) { 1175 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1176 // lifetime of `policy`. 1177 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1178 T::ready(policy); 1179 } 1180 1181 /// Driver's `verify` callback. 1182 /// 1183 /// # Safety 1184 /// 1185 /// - This function may only be called from the cpufreq C infrastructure. 1186 /// - The pointer arguments must be valid pointers. 1187 unsafe extern "C" fn verify_callback(ptr: *mut bindings::cpufreq_policy_data) -> c_int { 1188 from_result(|| { 1189 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1190 // lifetime of `policy`. 1191 let data = unsafe { PolicyData::from_raw_mut(ptr) }; 1192 T::verify(data).map(|()| 0) 1193 }) 1194 } 1195 1196 /// Driver's `setpolicy` callback. 1197 /// 1198 /// # Safety 1199 /// 1200 /// - This function may only be called from the cpufreq C infrastructure. 1201 /// - The pointer arguments must be valid pointers. 1202 unsafe extern "C" fn setpolicy_callback(ptr: *mut bindings::cpufreq_policy) -> c_int { 1203 from_result(|| { 1204 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1205 // lifetime of `policy`. 1206 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1207 T::setpolicy(policy).map(|()| 0) 1208 }) 1209 } 1210 1211 /// Driver's `target` callback. 1212 /// 1213 /// # Safety 1214 /// 1215 /// - This function may only be called from the cpufreq C infrastructure. 1216 /// - The pointer arguments must be valid pointers. 1217 unsafe extern "C" fn target_callback( 1218 ptr: *mut bindings::cpufreq_policy, 1219 target_freq: c_uint, 1220 relation: c_uint, 1221 ) -> c_int { 1222 from_result(|| { 1223 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1224 // lifetime of `policy`. 1225 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1226 T::target(policy, target_freq, Relation::new(relation)?).map(|()| 0) 1227 }) 1228 } 1229 1230 /// Driver's `target_index` callback. 1231 /// 1232 /// # Safety 1233 /// 1234 /// - This function may only be called from the cpufreq C infrastructure. 1235 /// - The pointer arguments must be valid pointers. 1236 unsafe extern "C" fn target_index_callback( 1237 ptr: *mut bindings::cpufreq_policy, 1238 index: c_uint, 1239 ) -> c_int { 1240 from_result(|| { 1241 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1242 // lifetime of `policy`. 1243 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1244 1245 // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the 1246 // frequency table. 1247 let index = unsafe { TableIndex::new(index as usize) }; 1248 1249 T::target_index(policy, index).map(|()| 0) 1250 }) 1251 } 1252 1253 /// Driver's `fast_switch` callback. 1254 /// 1255 /// # Safety 1256 /// 1257 /// - This function may only be called from the cpufreq C infrastructure. 1258 /// - The pointer arguments must be valid pointers. 1259 unsafe extern "C" fn fast_switch_callback( 1260 ptr: *mut bindings::cpufreq_policy, 1261 target_freq: c_uint, 1262 ) -> c_uint { 1263 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1264 // lifetime of `policy`. 1265 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1266 T::fast_switch(policy, target_freq) 1267 } 1268 1269 /// Driver's `adjust_perf` callback. 1270 /// 1271 /// # Safety 1272 /// 1273 /// - This function may only be called from the cpufreq C infrastructure. 1274 /// - The pointer arguments must be valid pointers. 1275 unsafe extern "C" fn adjust_perf_callback( 1276 ptr: *mut bindings::cpufreq_policy, 1277 min_perf: c_ulong, 1278 target_perf: c_ulong, 1279 max_perf: c_ulong, 1280 capacity: c_ulong, 1281 ) { 1282 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1283 // lifetime of `policy`. 1284 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1285 T::adjust_perf(policy, min_perf, target_perf, max_perf, capacity); 1286 } 1287 1288 /// Driver's `get_intermediate` callback. 1289 /// 1290 /// # Safety 1291 /// 1292 /// - This function may only be called from the cpufreq C infrastructure. 1293 /// - The pointer arguments must be valid pointers. 1294 unsafe extern "C" fn get_intermediate_callback( 1295 ptr: *mut bindings::cpufreq_policy, 1296 index: c_uint, 1297 ) -> c_uint { 1298 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1299 // lifetime of `policy`. 1300 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1301 1302 // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the 1303 // frequency table. 1304 let index = unsafe { TableIndex::new(index as usize) }; 1305 1306 T::get_intermediate(policy, index) 1307 } 1308 1309 /// Driver's `target_intermediate` callback. 1310 /// 1311 /// # Safety 1312 /// 1313 /// - This function may only be called from the cpufreq C infrastructure. 1314 /// - The pointer arguments must be valid pointers. 1315 unsafe extern "C" fn target_intermediate_callback( 1316 ptr: *mut bindings::cpufreq_policy, 1317 index: c_uint, 1318 ) -> c_int { 1319 from_result(|| { 1320 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1321 // lifetime of `policy`. 1322 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1323 1324 // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the 1325 // frequency table. 1326 let index = unsafe { TableIndex::new(index as usize) }; 1327 1328 T::target_intermediate(policy, index).map(|()| 0) 1329 }) 1330 } 1331 1332 /// Driver's `get` callback. 1333 /// 1334 /// # Safety 1335 /// 1336 /// - This function may only be called from the cpufreq C infrastructure. 1337 unsafe extern "C" fn get_callback(cpu: c_uint) -> c_uint { 1338 // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number. 1339 let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) }; 1340 1341 PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).unwrap_or(0)) 1342 } 1343 1344 /// Driver's `update_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 update_limits_callback(ptr: *mut bindings::cpufreq_policy) { 1351 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1352 // lifetime of `policy`. 1353 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1354 T::update_limits(policy); 1355 } 1356 1357 /// Driver's `bios_limit` callback. 1358 /// 1359 /// # Safety 1360 /// 1361 /// - This function may only be called from the cpufreq C infrastructure. 1362 /// - The pointer arguments must be valid pointers. 1363 unsafe extern "C" fn bios_limit_callback(cpu: c_int, limit: *mut c_uint) -> c_int { 1364 // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number. 1365 let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) }; 1366 1367 from_result(|| { 1368 let mut policy = PolicyCpu::from_cpu(cpu_id)?; 1369 let val = T::bios_limit(&mut policy)?; 1370 // SAFETY: `limit` is guaranteed by the C code to be valid. 1371 unsafe { 1372 *limit = val; 1373 } 1374 Ok(0) 1375 }) 1376 } 1377 1378 /// Driver's `set_boost` callback. 1379 /// 1380 /// # Safety 1381 /// 1382 /// - This function may only be called from the cpufreq C infrastructure. 1383 /// - The pointer arguments must be valid pointers. 1384 unsafe extern "C" fn set_boost_callback( 1385 ptr: *mut bindings::cpufreq_policy, 1386 state: c_int, 1387 ) -> c_int { 1388 from_result(|| { 1389 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1390 // lifetime of `policy`. 1391 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1392 T::set_boost(policy, state).map(|()| 0) 1393 }) 1394 } 1395 1396 /// Driver's `register_em` callback. 1397 /// 1398 /// # Safety 1399 /// 1400 /// - This function may only be called from the cpufreq C infrastructure. 1401 /// - The pointer arguments must be valid pointers. 1402 unsafe extern "C" fn register_em_callback(ptr: *mut bindings::cpufreq_policy) { 1403 // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1404 // lifetime of `policy`. 1405 let policy = unsafe { Policy::from_raw_mut(ptr) }; 1406 T::register_em(policy); 1407 } 1408 } 1409 1410 impl<T: Driver> Drop for Registration<T> { 1411 /// Unregisters with the cpufreq core. 1412 fn drop(&mut self) { 1413 // SAFETY: `self.0` is guaranteed to be valid for the lifetime of `Registration`. 1414 unsafe { bindings::cpufreq_unregister_driver(self.0.get_mut()) }; 1415 } 1416 } 1417