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