Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm-6.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more power management updates from Rafael Wysocki:
"These revert an x86 commit that introduced a nasty power regression on
some systems, fix PSCI cpuidle driver and ACPI cpufreq driver
regressions, add Rust abstractions for cpufreq, OPP, clk, and
cpumasks, add a Rust-based cpufreq-dt driver, and do a minor SCMI
cpufreq driver cleanup:

- Revert an x86 commit that went into 6.15 and caused idle power,
including power in suspend-to-idle, to rise rather dramatically on
systems booting with "nosmt" in the kernel command line (Rafael
Wysocki)

- Prevent freeing an uninitialized pointer in error path of
dt_idle_state_present() in the PSCI cpuidle driver (Dan Carpenter)

- Use KHz as the nominal_freq units in get_max_boost_ratio() in the
ACPI cpufreq driver (iGautham Shenoy)

- Add Rust abstractions for CPUFreq framework (Viresh Kumar)

- Add Rust abstractions for OPP framework (Viresh Kumar)

- Add basic Rust abstractions for Clk and Cpumask frameworks (Viresh
Kumar)

- Clean up the SCMI cpufreq driver somewhat (Mike Tipton)"

* tag 'pm-6.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (21 commits)
Revert "x86/smp: Eliminate mwait_play_dead_cpuid_hint()"
acpi-cpufreq: Fix nominal_freq units to KHz in get_max_boost_ratio()
rust: opp: Move `cfg(CONFIG_OF)` attribute to the top of doc test
cpuidle: psci: Fix uninitialized variable in dt_idle_state_present()
rust: opp: Make the doctest example depend on CONFIG_OF
cpufreq: scmi: Skip SCMI devices that aren't used by the CPUs
cpufreq: Add Rust-based cpufreq-dt driver
rust: opp: Extend OPP abstractions with cpufreq support
rust: cpufreq: Extend abstractions for driver registration
rust: cpufreq: Extend abstractions for policy and driver ops
rust: cpufreq: Add initial abstractions for cpufreq framework
rust: opp: Add abstractions for the configuration options
rust: opp: Add abstractions for the OPP table
rust: opp: Add initial abstractions for OPP framework
rust: cpu: Add from_cpu()
rust: macros: enable use of hyphens in module names
rust: clk: Add initial abstractions
rust: clk: Add helpers for Rust code
MAINTAINERS: Add entry for Rust cpumask API
rust: cpumask: Add initial abstractions
...

+3624 -22
+11
MAINTAINERS
··· 5952 5952 F: include/linux/clk-pr* 5953 5953 F: include/linux/clk/ 5954 5954 F: include/linux/of_clk.h 5955 + F: rust/helpers/clk.c 5956 + F: rust/kernel/clk.rs 5955 5957 X: drivers/clk/clkdev.c 5956 5958 5957 5959 COMMON INTERNET FILE SYSTEM CLIENT (CIFS and SMB3) ··· 6213 6211 F: include/linux/cpufreq.h 6214 6212 F: include/linux/sched/cpufreq.h 6215 6213 F: kernel/sched/cpufreq*.c 6214 + F: rust/kernel/cpufreq.rs 6216 6215 F: tools/testing/selftests/cpufreq/ 6217 6216 6218 6217 CPU HOTPLUG ··· 6227 6224 F: include/linux/smpboot.h 6228 6225 F: kernel/cpu.c 6229 6226 F: kernel/smpboot.* 6227 + F: rust/kernel/cpu.rs 6230 6228 6231 6229 CPU IDLE TIME MANAGEMENT FRAMEWORK 6232 6230 M: "Rafael J. Wysocki" <rafael@kernel.org> ··· 6311 6307 L: linux-riscv@lists.infradead.org 6312 6308 S: Maintained 6313 6309 F: drivers/cpuidle/cpuidle-riscv-sbi.c 6310 + 6311 + CPUMASK API [RUST] 6312 + M: Viresh Kumar <viresh.kumar@linaro.org> 6313 + R: Yury Norov <yury.norov@gmail.com> 6314 + S: Maintained 6315 + F: rust/kernel/cpumask.rs 6314 6316 6315 6317 CRAMFS FILESYSTEM 6316 6318 M: Nicolas Pitre <nico@fluxnic.net> ··· 18524 18514 F: Documentation/power/opp.rst 18525 18515 F: drivers/opp/ 18526 18516 F: include/linux/pm_opp.h 18517 + F: rust/kernel/opp.rs 18527 18518 18528 18519 OPL4 DRIVER 18529 18520 M: Clemens Ladisch <clemens@ladisch.de>
+47 -7
arch/x86/kernel/smpboot.c
··· 1244 1244 local_irq_disable(); 1245 1245 } 1246 1246 1247 - /* 1248 - * We need to flush the caches before going to sleep, lest we have 1249 - * dirty data in our caches when we come back up. 1250 - */ 1251 1247 void __noreturn mwait_play_dead(unsigned int eax_hint) 1252 1248 { 1253 1249 struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead); ··· 1287 1291 native_halt(); 1288 1292 } 1289 1293 } 1294 + } 1295 + 1296 + /* 1297 + * We need to flush the caches before going to sleep, lest we have 1298 + * dirty data in our caches when we come back up. 1299 + */ 1300 + static inline void mwait_play_dead_cpuid_hint(void) 1301 + { 1302 + unsigned int eax, ebx, ecx, edx; 1303 + unsigned int highest_cstate = 0; 1304 + unsigned int highest_subcstate = 0; 1305 + int i; 1306 + 1307 + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || 1308 + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) 1309 + return; 1310 + if (!this_cpu_has(X86_FEATURE_MWAIT)) 1311 + return; 1312 + if (!this_cpu_has(X86_FEATURE_CLFLUSH)) 1313 + return; 1314 + 1315 + eax = CPUID_LEAF_MWAIT; 1316 + ecx = 0; 1317 + native_cpuid(&eax, &ebx, &ecx, &edx); 1318 + 1319 + /* 1320 + * eax will be 0 if EDX enumeration is not valid. 1321 + * Initialized below to cstate, sub_cstate value when EDX is valid. 1322 + */ 1323 + if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED)) { 1324 + eax = 0; 1325 + } else { 1326 + edx >>= MWAIT_SUBSTATE_SIZE; 1327 + for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) { 1328 + if (edx & MWAIT_SUBSTATE_MASK) { 1329 + highest_cstate = i; 1330 + highest_subcstate = edx & MWAIT_SUBSTATE_MASK; 1331 + } 1332 + } 1333 + eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | 1334 + (highest_subcstate - 1); 1335 + } 1336 + 1337 + mwait_play_dead(eax); 1290 1338 } 1291 1339 1292 1340 /* ··· 1383 1343 play_dead_common(); 1384 1344 tboot_shutdown(TB_SHUTDOWN_WFS); 1385 1345 1386 - /* Below returns only on error. */ 1387 - cpuidle_play_dead(); 1388 - hlt_play_dead(); 1346 + mwait_play_dead_cpuid_hint(); 1347 + if (cpuidle_play_dead()) 1348 + hlt_play_dead(); 1389 1349 } 1390 1350 1391 1351 #else /* ... !CONFIG_HOTPLUG_CPU */
+12
drivers/cpufreq/Kconfig
··· 217 217 218 218 If in doubt, say N. 219 219 220 + config CPUFREQ_DT_RUST 221 + tristate "Rust based Generic DT based cpufreq driver" 222 + depends on HAVE_CLK && OF && RUST 223 + select CPUFREQ_DT_PLATDEV 224 + select PM_OPP 225 + help 226 + This adds a Rust based generic DT based cpufreq driver for frequency 227 + management. It supports both uniprocessor (UP) and symmetric 228 + multiprocessor (SMP) systems. 229 + 230 + If in doubt, say N. 231 + 220 232 config CPUFREQ_VIRT 221 233 tristate "Virtual cpufreq driver" 222 234 depends on GENERIC_ARCH_TOPOLOGY
+1
drivers/cpufreq/Makefile
··· 15 15 obj-$(CONFIG_CPU_FREQ_GOV_ATTR_SET) += cpufreq_governor_attr_set.o 16 16 17 17 obj-$(CONFIG_CPUFREQ_DT) += cpufreq-dt.o 18 + obj-$(CONFIG_CPUFREQ_DT_RUST) += rcpufreq_dt.o 18 19 obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o 19 20 obj-$(CONFIG_CPUFREQ_VIRT) += virtual-cpufreq.o 20 21
+1 -1
drivers/cpufreq/acpi-cpufreq.c
··· 660 660 nominal_perf = perf_caps.nominal_perf; 661 661 662 662 if (nominal_freq) 663 - *nominal_freq = perf_caps.nominal_freq; 663 + *nominal_freq = perf_caps.nominal_freq * 1000; 664 664 665 665 if (!highest_perf || !nominal_perf) { 666 666 pr_debug("CPU%d: highest or nominal performance missing\n", cpu);
+226
drivers/cpufreq/rcpufreq_dt.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! Rust based implementation of the cpufreq-dt driver. 4 + 5 + use kernel::{ 6 + c_str, 7 + clk::Clk, 8 + cpu, cpufreq, 9 + cpumask::CpumaskVar, 10 + device::{Core, Device}, 11 + error::code::*, 12 + fmt, 13 + macros::vtable, 14 + module_platform_driver, of, opp, platform, 15 + prelude::*, 16 + str::CString, 17 + sync::Arc, 18 + }; 19 + 20 + /// Finds exact supply name from the OF node. 21 + fn find_supply_name_exact(dev: &Device, name: &str) -> Option<CString> { 22 + let prop_name = CString::try_from_fmt(fmt!("{}-supply", name)).ok()?; 23 + dev.property_present(&prop_name) 24 + .then(|| CString::try_from_fmt(fmt!("{name}")).ok()) 25 + .flatten() 26 + } 27 + 28 + /// Finds supply name for the CPU from DT. 29 + fn find_supply_names(dev: &Device, cpu: u32) -> Option<KVec<CString>> { 30 + // Try "cpu0" for older DTs, fallback to "cpu". 31 + let name = (cpu == 0) 32 + .then(|| find_supply_name_exact(dev, "cpu0")) 33 + .flatten() 34 + .or_else(|| find_supply_name_exact(dev, "cpu"))?; 35 + 36 + let mut list = KVec::with_capacity(1, GFP_KERNEL).ok()?; 37 + list.push(name, GFP_KERNEL).ok()?; 38 + 39 + Some(list) 40 + } 41 + 42 + /// Represents the cpufreq dt device. 43 + struct CPUFreqDTDevice { 44 + opp_table: opp::Table, 45 + freq_table: opp::FreqTable, 46 + _mask: CpumaskVar, 47 + _token: Option<opp::ConfigToken>, 48 + _clk: Clk, 49 + } 50 + 51 + #[derive(Default)] 52 + struct CPUFreqDTDriver; 53 + 54 + #[vtable] 55 + impl opp::ConfigOps for CPUFreqDTDriver {} 56 + 57 + #[vtable] 58 + impl cpufreq::Driver for CPUFreqDTDriver { 59 + const NAME: &'static CStr = c_str!("cpufreq-dt"); 60 + const FLAGS: u16 = cpufreq::flags::NEED_INITIAL_FREQ_CHECK | cpufreq::flags::IS_COOLING_DEV; 61 + const BOOST_ENABLED: bool = true; 62 + 63 + type PData = Arc<CPUFreqDTDevice>; 64 + 65 + fn init(policy: &mut cpufreq::Policy) -> Result<Self::PData> { 66 + let cpu = policy.cpu(); 67 + // SAFETY: The CPU device is only used during init; it won't get hot-unplugged. The cpufreq 68 + // core registers with CPU notifiers and the cpufreq core/driver won't use the CPU device, 69 + // once the CPU is hot-unplugged. 70 + let dev = unsafe { cpu::from_cpu(cpu)? }; 71 + let mut mask = CpumaskVar::new_zero(GFP_KERNEL)?; 72 + 73 + mask.set(cpu); 74 + 75 + let token = find_supply_names(dev, cpu) 76 + .map(|names| { 77 + opp::Config::<Self>::new() 78 + .set_regulator_names(names)? 79 + .set(dev) 80 + }) 81 + .transpose()?; 82 + 83 + // Get OPP-sharing information from "operating-points-v2" bindings. 84 + let fallback = match opp::Table::of_sharing_cpus(dev, &mut mask) { 85 + Ok(()) => false, 86 + Err(e) if e == ENOENT => { 87 + // "operating-points-v2" not supported. If the platform hasn't 88 + // set sharing CPUs, fallback to all CPUs share the `Policy` 89 + // for backward compatibility. 90 + opp::Table::sharing_cpus(dev, &mut mask).is_err() 91 + } 92 + Err(e) => return Err(e), 93 + }; 94 + 95 + // Initialize OPP tables for all policy cpus. 96 + // 97 + // For platforms not using "operating-points-v2" bindings, we do this 98 + // before updating policy cpus. Otherwise, we will end up creating 99 + // duplicate OPPs for the CPUs. 100 + // 101 + // OPPs might be populated at runtime, don't fail for error here unless 102 + // it is -EPROBE_DEFER. 103 + let mut opp_table = match opp::Table::from_of_cpumask(dev, &mut mask) { 104 + Ok(table) => table, 105 + Err(e) => { 106 + if e == EPROBE_DEFER { 107 + return Err(e); 108 + } 109 + 110 + // The table is added dynamically ? 111 + opp::Table::from_dev(dev)? 112 + } 113 + }; 114 + 115 + // The OPP table must be initialized, statically or dynamically, by this point. 116 + opp_table.opp_count()?; 117 + 118 + // Set sharing cpus for fallback scenario. 119 + if fallback { 120 + mask.setall(); 121 + opp_table.set_sharing_cpus(&mut mask)?; 122 + } 123 + 124 + let mut transition_latency = opp_table.max_transition_latency_ns() as u32; 125 + if transition_latency == 0 { 126 + transition_latency = cpufreq::ETERNAL_LATENCY_NS; 127 + } 128 + 129 + policy 130 + .set_dvfs_possible_from_any_cpu(true) 131 + .set_suspend_freq(opp_table.suspend_freq()) 132 + .set_transition_latency_ns(transition_latency); 133 + 134 + let freq_table = opp_table.cpufreq_table()?; 135 + // SAFETY: The `freq_table` is not dropped while it is getting used by the C code. 136 + unsafe { policy.set_freq_table(&freq_table) }; 137 + 138 + // SAFETY: The returned `clk` is not dropped while it is getting used by the C code. 139 + let clk = unsafe { policy.set_clk(dev, None)? }; 140 + 141 + mask.copy(policy.cpus()); 142 + 143 + Ok(Arc::new( 144 + CPUFreqDTDevice { 145 + opp_table, 146 + freq_table, 147 + _mask: mask, 148 + _token: token, 149 + _clk: clk, 150 + }, 151 + GFP_KERNEL, 152 + )?) 153 + } 154 + 155 + fn exit(_policy: &mut cpufreq::Policy, _data: Option<Self::PData>) -> Result { 156 + Ok(()) 157 + } 158 + 159 + fn online(_policy: &mut cpufreq::Policy) -> Result { 160 + // We did light-weight tear down earlier, nothing to do here. 161 + Ok(()) 162 + } 163 + 164 + fn offline(_policy: &mut cpufreq::Policy) -> Result { 165 + // Preserve policy->data and don't free resources on light-weight 166 + // tear down. 167 + Ok(()) 168 + } 169 + 170 + fn suspend(policy: &mut cpufreq::Policy) -> Result { 171 + policy.generic_suspend() 172 + } 173 + 174 + fn verify(data: &mut cpufreq::PolicyData) -> Result { 175 + data.generic_verify() 176 + } 177 + 178 + fn target_index(policy: &mut cpufreq::Policy, index: cpufreq::TableIndex) -> Result { 179 + let Some(data) = policy.data::<Self::PData>() else { 180 + return Err(ENOENT); 181 + }; 182 + 183 + let freq = data.freq_table.freq(index)?; 184 + data.opp_table.set_rate(freq) 185 + } 186 + 187 + fn get(policy: &mut cpufreq::Policy) -> Result<u32> { 188 + policy.generic_get() 189 + } 190 + 191 + fn set_boost(_policy: &mut cpufreq::Policy, _state: i32) -> Result { 192 + Ok(()) 193 + } 194 + 195 + fn register_em(policy: &mut cpufreq::Policy) { 196 + policy.register_em_opp() 197 + } 198 + } 199 + 200 + kernel::of_device_table!( 201 + OF_TABLE, 202 + MODULE_OF_TABLE, 203 + <CPUFreqDTDriver as platform::Driver>::IdInfo, 204 + [(of::DeviceId::new(c_str!("operating-points-v2")), ())] 205 + ); 206 + 207 + impl platform::Driver for CPUFreqDTDriver { 208 + type IdInfo = (); 209 + const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE); 210 + 211 + fn probe( 212 + pdev: &platform::Device<Core>, 213 + _id_info: Option<&Self::IdInfo>, 214 + ) -> Result<Pin<KBox<Self>>> { 215 + cpufreq::Registration::<CPUFreqDTDriver>::new_foreign_owned(pdev.as_ref())?; 216 + Ok(KBox::new(Self {}, GFP_KERNEL)?.into()) 217 + } 218 + } 219 + 220 + module_platform_driver! { 221 + type: CPUFreqDTDriver, 222 + name: "cpufreq-dt", 223 + author: "Viresh Kumar <viresh.kumar@linaro.org>", 224 + description: "Generic CPUFreq DT driver", 225 + license: "GPL v2", 226 + }
+35 -1
drivers/cpufreq/scmi-cpufreq.c
··· 393 393 .set_boost = cpufreq_boost_set_sw, 394 394 }; 395 395 396 + static bool scmi_dev_used_by_cpus(struct device *scmi_dev) 397 + { 398 + struct device_node *scmi_np = dev_of_node(scmi_dev); 399 + struct device_node *cpu_np, *np; 400 + struct device *cpu_dev; 401 + int cpu, idx; 402 + 403 + if (!scmi_np) 404 + return false; 405 + 406 + for_each_possible_cpu(cpu) { 407 + cpu_dev = get_cpu_device(cpu); 408 + if (!cpu_dev) 409 + continue; 410 + 411 + cpu_np = dev_of_node(cpu_dev); 412 + 413 + np = of_parse_phandle(cpu_np, "clocks", 0); 414 + of_node_put(np); 415 + 416 + if (np == scmi_np) 417 + return true; 418 + 419 + idx = of_property_match_string(cpu_np, "power-domain-names", "perf"); 420 + np = of_parse_phandle(cpu_np, "power-domains", idx); 421 + of_node_put(np); 422 + 423 + if (np == scmi_np) 424 + return true; 425 + } 426 + 427 + return false; 428 + } 429 + 396 430 static int scmi_cpufreq_probe(struct scmi_device *sdev) 397 431 { 398 432 int ret; ··· 435 401 436 402 handle = sdev->handle; 437 403 438 - if (!handle) 404 + if (!handle || !scmi_dev_used_by_cpus(dev)) 439 405 return -ENODEV; 440 406 441 407 scmi_cpufreq_driver.driver_data = sdev;
+4 -5
drivers/cpuidle/cpuidle-psci.c
··· 456 456 457 457 static bool __init dt_idle_state_present(void) 458 458 { 459 - struct device_node *cpu_node __free(device_node); 460 - struct device_node *state_node __free(device_node); 461 - 462 - cpu_node = of_cpu_device_node_get(cpumask_first(cpu_possible_mask)); 459 + struct device_node *cpu_node __free(device_node) = 460 + of_cpu_device_node_get(cpumask_first(cpu_possible_mask)); 463 461 if (!cpu_node) 464 462 return false; 465 463 466 - state_node = of_get_cpu_state_node(cpu_node, 0); 464 + struct device_node *state_node __free(device_node) = 465 + of_get_cpu_state_node(cpu_node, 0); 467 466 if (!state_node) 468 467 return false; 469 468
+4
rust/bindings/bindings_helper.h
··· 16 16 #include <linux/blk-mq.h> 17 17 #include <linux/blk_types.h> 18 18 #include <linux/blkdev.h> 19 + #include <linux/clk.h> 19 20 #include <linux/configfs.h> 21 + #include <linux/cpu.h> 22 + #include <linux/cpufreq.h> 20 23 #include <linux/cpumask.h> 21 24 #include <linux/cred.h> 22 25 #include <linux/device/faux.h> ··· 38 35 #include <linux/phy.h> 39 36 #include <linux/pid_namespace.h> 40 37 #include <linux/platform_device.h> 38 + #include <linux/pm_opp.h> 41 39 #include <linux/poll.h> 42 40 #include <linux/property.h> 43 41 #include <linux/refcount.h>
+66
rust/helpers/clk.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/clk.h> 4 + 5 + /* 6 + * The "inline" implementation of below helpers are only available when 7 + * CONFIG_HAVE_CLK or CONFIG_HAVE_CLK_PREPARE aren't set. 8 + */ 9 + #ifndef CONFIG_HAVE_CLK 10 + struct clk *rust_helper_clk_get(struct device *dev, const char *id) 11 + { 12 + return clk_get(dev, id); 13 + } 14 + 15 + void rust_helper_clk_put(struct clk *clk) 16 + { 17 + clk_put(clk); 18 + } 19 + 20 + int rust_helper_clk_enable(struct clk *clk) 21 + { 22 + return clk_enable(clk); 23 + } 24 + 25 + void rust_helper_clk_disable(struct clk *clk) 26 + { 27 + clk_disable(clk); 28 + } 29 + 30 + unsigned long rust_helper_clk_get_rate(struct clk *clk) 31 + { 32 + return clk_get_rate(clk); 33 + } 34 + 35 + int rust_helper_clk_set_rate(struct clk *clk, unsigned long rate) 36 + { 37 + return clk_set_rate(clk, rate); 38 + } 39 + #endif 40 + 41 + #ifndef CONFIG_HAVE_CLK_PREPARE 42 + int rust_helper_clk_prepare(struct clk *clk) 43 + { 44 + return clk_prepare(clk); 45 + } 46 + 47 + void rust_helper_clk_unprepare(struct clk *clk) 48 + { 49 + clk_unprepare(clk); 50 + } 51 + #endif 52 + 53 + struct clk *rust_helper_clk_get_optional(struct device *dev, const char *id) 54 + { 55 + return clk_get_optional(dev, id); 56 + } 57 + 58 + int rust_helper_clk_prepare_enable(struct clk *clk) 59 + { 60 + return clk_prepare_enable(clk); 61 + } 62 + 63 + void rust_helper_clk_disable_unprepare(struct clk *clk) 64 + { 65 + clk_disable_unprepare(clk); 66 + }
+10
rust/helpers/cpufreq.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/cpufreq.h> 4 + 5 + #ifdef CONFIG_CPU_FREQ 6 + void rust_helper_cpufreq_register_em_with_opp(struct cpufreq_policy *policy) 7 + { 8 + cpufreq_register_em_with_opp(policy); 9 + } 10 + #endif
+25
rust/helpers/cpumask.c
··· 7 7 cpumask_set_cpu(cpu, dstp); 8 8 } 9 9 10 + void rust_helper___cpumask_set_cpu(unsigned int cpu, struct cpumask *dstp) 11 + { 12 + __cpumask_set_cpu(cpu, dstp); 13 + } 14 + 10 15 void rust_helper_cpumask_clear_cpu(int cpu, struct cpumask *dstp) 11 16 { 12 17 cpumask_clear_cpu(cpu, dstp); 13 18 } 14 19 20 + void rust_helper___cpumask_clear_cpu(int cpu, struct cpumask *dstp) 21 + { 22 + __cpumask_clear_cpu(cpu, dstp); 23 + } 24 + 25 + bool rust_helper_cpumask_test_cpu(int cpu, struct cpumask *srcp) 26 + { 27 + return cpumask_test_cpu(cpu, srcp); 28 + } 29 + 15 30 void rust_helper_cpumask_setall(struct cpumask *dstp) 16 31 { 17 32 cpumask_setall(dstp); 33 + } 34 + 35 + bool rust_helper_cpumask_empty(struct cpumask *srcp) 36 + { 37 + return cpumask_empty(srcp); 38 + } 39 + 40 + bool rust_helper_cpumask_full(struct cpumask *srcp) 41 + { 42 + return cpumask_full(srcp); 18 43 } 19 44 20 45 unsigned int rust_helper_cpumask_weight(struct cpumask *srcp)
+2
rust/helpers/helpers.c
··· 12 12 #include "bug.c" 13 13 #include "build_assert.c" 14 14 #include "build_bug.c" 15 + #include "clk.c" 16 + #include "cpufreq.c" 15 17 #include "cpumask.c" 16 18 #include "cred.c" 17 19 #include "device.c"
+334
rust/kernel/clk.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! Clock abstractions. 4 + //! 5 + //! C header: [`include/linux/clk.h`](srctree/include/linux/clk.h) 6 + //! 7 + //! Reference: <https://docs.kernel.org/driver-api/clk.html> 8 + 9 + use crate::ffi::c_ulong; 10 + 11 + /// The frequency unit. 12 + /// 13 + /// Represents a frequency in hertz, wrapping a [`c_ulong`] value. 14 + /// 15 + /// ## Examples 16 + /// 17 + /// ``` 18 + /// use kernel::clk::Hertz; 19 + /// 20 + /// let hz = 1_000_000_000; 21 + /// let rate = Hertz(hz); 22 + /// 23 + /// assert_eq!(rate.as_hz(), hz); 24 + /// assert_eq!(rate, Hertz(hz)); 25 + /// assert_eq!(rate, Hertz::from_khz(hz / 1_000)); 26 + /// assert_eq!(rate, Hertz::from_mhz(hz / 1_000_000)); 27 + /// assert_eq!(rate, Hertz::from_ghz(hz / 1_000_000_000)); 28 + /// ``` 29 + #[derive(Copy, Clone, PartialEq, Eq, Debug)] 30 + pub struct Hertz(pub c_ulong); 31 + 32 + impl Hertz { 33 + /// Create a new instance from kilohertz (kHz) 34 + pub fn from_khz(khz: c_ulong) -> Self { 35 + Self(khz * 1_000) 36 + } 37 + 38 + /// Create a new instance from megahertz (MHz) 39 + pub fn from_mhz(mhz: c_ulong) -> Self { 40 + Self(mhz * 1_000_000) 41 + } 42 + 43 + /// Create a new instance from gigahertz (GHz) 44 + pub fn from_ghz(ghz: c_ulong) -> Self { 45 + Self(ghz * 1_000_000_000) 46 + } 47 + 48 + /// Get the frequency in hertz 49 + pub fn as_hz(&self) -> c_ulong { 50 + self.0 51 + } 52 + 53 + /// Get the frequency in kilohertz 54 + pub fn as_khz(&self) -> c_ulong { 55 + self.0 / 1_000 56 + } 57 + 58 + /// Get the frequency in megahertz 59 + pub fn as_mhz(&self) -> c_ulong { 60 + self.0 / 1_000_000 61 + } 62 + 63 + /// Get the frequency in gigahertz 64 + pub fn as_ghz(&self) -> c_ulong { 65 + self.0 / 1_000_000_000 66 + } 67 + } 68 + 69 + impl From<Hertz> for c_ulong { 70 + fn from(freq: Hertz) -> Self { 71 + freq.0 72 + } 73 + } 74 + 75 + #[cfg(CONFIG_COMMON_CLK)] 76 + mod common_clk { 77 + use super::Hertz; 78 + use crate::{ 79 + device::Device, 80 + error::{from_err_ptr, to_result, Result}, 81 + prelude::*, 82 + }; 83 + 84 + use core::{ops::Deref, ptr}; 85 + 86 + /// A reference-counted clock. 87 + /// 88 + /// Rust abstraction for the C [`struct clk`]. 89 + /// 90 + /// # Invariants 91 + /// 92 + /// A [`Clk`] instance holds either a pointer to a valid [`struct clk`] created by the C 93 + /// portion of the kernel or a NULL pointer. 94 + /// 95 + /// Instances of this type are reference-counted. Calling [`Clk::get`] ensures that the 96 + /// allocation remains valid for the lifetime of the [`Clk`]. 97 + /// 98 + /// ## Examples 99 + /// 100 + /// The following example demonstrates how to obtain and configure a clock for a device. 101 + /// 102 + /// ``` 103 + /// use kernel::c_str; 104 + /// use kernel::clk::{Clk, Hertz}; 105 + /// use kernel::device::Device; 106 + /// use kernel::error::Result; 107 + /// 108 + /// fn configure_clk(dev: &Device) -> Result { 109 + /// let clk = Clk::get(dev, Some(c_str!("apb_clk")))?; 110 + /// 111 + /// clk.prepare_enable()?; 112 + /// 113 + /// let expected_rate = Hertz::from_ghz(1); 114 + /// 115 + /// if clk.rate() != expected_rate { 116 + /// clk.set_rate(expected_rate)?; 117 + /// } 118 + /// 119 + /// clk.disable_unprepare(); 120 + /// Ok(()) 121 + /// } 122 + /// ``` 123 + /// 124 + /// [`struct clk`]: https://docs.kernel.org/driver-api/clk.html 125 + #[repr(transparent)] 126 + pub struct Clk(*mut bindings::clk); 127 + 128 + impl Clk { 129 + /// Gets [`Clk`] corresponding to a [`Device`] and a connection id. 130 + /// 131 + /// Equivalent to the kernel's [`clk_get`] API. 132 + /// 133 + /// [`clk_get`]: https://docs.kernel.org/core-api/kernel-api.html#c.clk_get 134 + pub fn get(dev: &Device, name: Option<&CStr>) -> Result<Self> { 135 + let con_id = if let Some(name) = name { 136 + name.as_ptr() 137 + } else { 138 + ptr::null() 139 + }; 140 + 141 + // SAFETY: It is safe to call [`clk_get`] for a valid device pointer. 142 + // 143 + // INVARIANT: The reference-count is decremented when [`Clk`] goes out of scope. 144 + Ok(Self(from_err_ptr(unsafe { 145 + bindings::clk_get(dev.as_raw(), con_id) 146 + })?)) 147 + } 148 + 149 + /// Obtain the raw [`struct clk`] pointer. 150 + #[inline] 151 + pub fn as_raw(&self) -> *mut bindings::clk { 152 + self.0 153 + } 154 + 155 + /// Enable the clock. 156 + /// 157 + /// Equivalent to the kernel's [`clk_enable`] API. 158 + /// 159 + /// [`clk_enable`]: https://docs.kernel.org/core-api/kernel-api.html#c.clk_enable 160 + #[inline] 161 + pub fn enable(&self) -> Result { 162 + // SAFETY: By the type invariants, self.as_raw() is a valid argument for 163 + // [`clk_enable`]. 164 + to_result(unsafe { bindings::clk_enable(self.as_raw()) }) 165 + } 166 + 167 + /// Disable the clock. 168 + /// 169 + /// Equivalent to the kernel's [`clk_disable`] API. 170 + /// 171 + /// [`clk_disable`]: https://docs.kernel.org/core-api/kernel-api.html#c.clk_disable 172 + #[inline] 173 + pub fn disable(&self) { 174 + // SAFETY: By the type invariants, self.as_raw() is a valid argument for 175 + // [`clk_disable`]. 176 + unsafe { bindings::clk_disable(self.as_raw()) }; 177 + } 178 + 179 + /// Prepare the clock. 180 + /// 181 + /// Equivalent to the kernel's [`clk_prepare`] API. 182 + /// 183 + /// [`clk_prepare`]: https://docs.kernel.org/core-api/kernel-api.html#c.clk_prepare 184 + #[inline] 185 + pub fn prepare(&self) -> Result { 186 + // SAFETY: By the type invariants, self.as_raw() is a valid argument for 187 + // [`clk_prepare`]. 188 + to_result(unsafe { bindings::clk_prepare(self.as_raw()) }) 189 + } 190 + 191 + /// Unprepare the clock. 192 + /// 193 + /// Equivalent to the kernel's [`clk_unprepare`] API. 194 + /// 195 + /// [`clk_unprepare`]: https://docs.kernel.org/core-api/kernel-api.html#c.clk_unprepare 196 + #[inline] 197 + pub fn unprepare(&self) { 198 + // SAFETY: By the type invariants, self.as_raw() is a valid argument for 199 + // [`clk_unprepare`]. 200 + unsafe { bindings::clk_unprepare(self.as_raw()) }; 201 + } 202 + 203 + /// Prepare and enable the clock. 204 + /// 205 + /// Equivalent to calling [`Clk::prepare`] followed by [`Clk::enable`]. 206 + #[inline] 207 + pub fn prepare_enable(&self) -> Result { 208 + // SAFETY: By the type invariants, self.as_raw() is a valid argument for 209 + // [`clk_prepare_enable`]. 210 + to_result(unsafe { bindings::clk_prepare_enable(self.as_raw()) }) 211 + } 212 + 213 + /// Disable and unprepare the clock. 214 + /// 215 + /// Equivalent to calling [`Clk::disable`] followed by [`Clk::unprepare`]. 216 + #[inline] 217 + pub fn disable_unprepare(&self) { 218 + // SAFETY: By the type invariants, self.as_raw() is a valid argument for 219 + // [`clk_disable_unprepare`]. 220 + unsafe { bindings::clk_disable_unprepare(self.as_raw()) }; 221 + } 222 + 223 + /// Get clock's rate. 224 + /// 225 + /// Equivalent to the kernel's [`clk_get_rate`] API. 226 + /// 227 + /// [`clk_get_rate`]: https://docs.kernel.org/core-api/kernel-api.html#c.clk_get_rate 228 + #[inline] 229 + pub fn rate(&self) -> Hertz { 230 + // SAFETY: By the type invariants, self.as_raw() is a valid argument for 231 + // [`clk_get_rate`]. 232 + Hertz(unsafe { bindings::clk_get_rate(self.as_raw()) }) 233 + } 234 + 235 + /// Set clock's rate. 236 + /// 237 + /// Equivalent to the kernel's [`clk_set_rate`] API. 238 + /// 239 + /// [`clk_set_rate`]: https://docs.kernel.org/core-api/kernel-api.html#c.clk_set_rate 240 + #[inline] 241 + pub fn set_rate(&self, rate: Hertz) -> Result { 242 + // SAFETY: By the type invariants, self.as_raw() is a valid argument for 243 + // [`clk_set_rate`]. 244 + to_result(unsafe { bindings::clk_set_rate(self.as_raw(), rate.as_hz()) }) 245 + } 246 + } 247 + 248 + impl Drop for Clk { 249 + fn drop(&mut self) { 250 + // SAFETY: By the type invariants, self.as_raw() is a valid argument for [`clk_put`]. 251 + unsafe { bindings::clk_put(self.as_raw()) }; 252 + } 253 + } 254 + 255 + /// A reference-counted optional clock. 256 + /// 257 + /// A lightweight wrapper around an optional [`Clk`]. An [`OptionalClk`] represents a [`Clk`] 258 + /// that a driver can function without but may improve performance or enable additional 259 + /// features when available. 260 + /// 261 + /// # Invariants 262 + /// 263 + /// An [`OptionalClk`] instance encapsulates a [`Clk`] with either a valid [`struct clk`] or 264 + /// `NULL` pointer. 265 + /// 266 + /// Instances of this type are reference-counted. Calling [`OptionalClk::get`] ensures that the 267 + /// allocation remains valid for the lifetime of the [`OptionalClk`]. 268 + /// 269 + /// ## Examples 270 + /// 271 + /// The following example demonstrates how to obtain and configure an optional clock for a 272 + /// device. The code functions correctly whether or not the clock is available. 273 + /// 274 + /// ``` 275 + /// use kernel::c_str; 276 + /// use kernel::clk::{OptionalClk, Hertz}; 277 + /// use kernel::device::Device; 278 + /// use kernel::error::Result; 279 + /// 280 + /// fn configure_clk(dev: &Device) -> Result { 281 + /// let clk = OptionalClk::get(dev, Some(c_str!("apb_clk")))?; 282 + /// 283 + /// clk.prepare_enable()?; 284 + /// 285 + /// let expected_rate = Hertz::from_ghz(1); 286 + /// 287 + /// if clk.rate() != expected_rate { 288 + /// clk.set_rate(expected_rate)?; 289 + /// } 290 + /// 291 + /// clk.disable_unprepare(); 292 + /// Ok(()) 293 + /// } 294 + /// ``` 295 + /// 296 + /// [`struct clk`]: https://docs.kernel.org/driver-api/clk.html 297 + pub struct OptionalClk(Clk); 298 + 299 + impl OptionalClk { 300 + /// Gets [`OptionalClk`] corresponding to a [`Device`] and a connection id. 301 + /// 302 + /// Equivalent to the kernel's [`clk_get_optional`] API. 303 + /// 304 + /// [`clk_get_optional`]: 305 + /// https://docs.kernel.org/core-api/kernel-api.html#c.clk_get_optional 306 + pub fn get(dev: &Device, name: Option<&CStr>) -> Result<Self> { 307 + let con_id = if let Some(name) = name { 308 + name.as_ptr() 309 + } else { 310 + ptr::null() 311 + }; 312 + 313 + // SAFETY: It is safe to call [`clk_get_optional`] for a valid device pointer. 314 + // 315 + // INVARIANT: The reference-count is decremented when [`OptionalClk`] goes out of 316 + // scope. 317 + Ok(Self(Clk(from_err_ptr(unsafe { 318 + bindings::clk_get_optional(dev.as_raw(), con_id) 319 + })?))) 320 + } 321 + } 322 + 323 + // Make [`OptionalClk`] behave like [`Clk`]. 324 + impl Deref for OptionalClk { 325 + type Target = Clk; 326 + 327 + fn deref(&self) -> &Clk { 328 + &self.0 329 + } 330 + } 331 + } 332 + 333 + #[cfg(CONFIG_COMMON_CLK)] 334 + pub use common_clk::*;
+30
rust/kernel/cpu.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! Generic CPU definitions. 4 + //! 5 + //! C header: [`include/linux/cpu.h`](srctree/include/linux/cpu.h) 6 + 7 + use crate::{bindings, device::Device, error::Result, prelude::ENODEV}; 8 + 9 + /// Creates a new instance of CPU's device. 10 + /// 11 + /// # Safety 12 + /// 13 + /// Reference counting is not implemented for the CPU device in the C code. When a CPU is 14 + /// hot-unplugged, the corresponding CPU device is unregistered, but its associated memory 15 + /// is not freed. 16 + /// 17 + /// Callers must ensure that the CPU device is not used after it has been unregistered. 18 + /// This can be achieved, for example, by registering a CPU hotplug notifier and removing 19 + /// any references to the CPU device within the notifier's callback. 20 + pub unsafe fn from_cpu(cpu: u32) -> Result<&'static Device> { 21 + // SAFETY: It is safe to call `get_cpu_device()` for any CPU. 22 + let ptr = unsafe { bindings::get_cpu_device(cpu) }; 23 + if ptr.is_null() { 24 + return Err(ENODEV); 25 + } 26 + 27 + // SAFETY: The pointer returned by `get_cpu_device()`, if not `NULL`, is a valid pointer to 28 + // a `struct device` and is never freed by the C code. 29 + Ok(unsafe { Device::as_ref(ptr) }) 30 + }
+1321
rust/kernel/cpufreq.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! CPU frequency scaling. 4 + //! 5 + //! This module provides rust abstractions for interacting with the cpufreq subsystem. 6 + //! 7 + //! C header: [`include/linux/cpufreq.h`](srctree/include/linux/cpufreq.h) 8 + //! 9 + //! Reference: <https://docs.kernel.org/admin-guide/pm/cpufreq.html> 10 + 11 + use crate::{ 12 + clk::Hertz, 13 + cpumask, 14 + device::{Bound, Device}, 15 + devres::Devres, 16 + error::{code::*, from_err_ptr, from_result, to_result, Result, VTABLE_DEFAULT_ERROR}, 17 + ffi::{c_char, c_ulong}, 18 + prelude::*, 19 + types::ForeignOwnable, 20 + types::Opaque, 21 + }; 22 + 23 + #[cfg(CONFIG_COMMON_CLK)] 24 + use crate::clk::Clk; 25 + 26 + use core::{ 27 + cell::UnsafeCell, 28 + marker::PhantomData, 29 + mem::MaybeUninit, 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 ETERNAL_LATENCY_NS: u32 = bindings::CPUFREQ_ETERNAL as u32; 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 new entry to the table. 365 + pub fn add(&mut self, freq: Hertz, flags: u32, driver_data: u32) -> Result { 366 + // Adds the new entry at the end of the vector. 367 + Ok(self.entries.push( 368 + bindings::cpufreq_frequency_table { 369 + flags, 370 + driver_data, 371 + frequency: freq.as_khz() as u32, 372 + }, 373 + GFP_KERNEL, 374 + )?) 375 + } 376 + 377 + /// Consumes the [`TableBuilder`] and returns [`TableBox`]. 378 + pub fn to_table(mut self) -> Result<TableBox> { 379 + // Add last entry to the table. 380 + self.add(Hertz(c_ulong::MAX), 0, 0)?; 381 + 382 + TableBox::new(self.entries) 383 + } 384 + } 385 + 386 + /// CPU frequency policy. 387 + /// 388 + /// Rust abstraction for the C `struct cpufreq_policy`. 389 + /// 390 + /// # Invariants 391 + /// 392 + /// A [`Policy`] instance always corresponds to a valid C `struct cpufreq_policy`. 393 + /// 394 + /// The callers must ensure that the `struct cpufreq_policy` is valid for access and remains valid 395 + /// for the lifetime of the returned reference. 396 + /// 397 + /// ## Examples 398 + /// 399 + /// The following example demonstrates how to create a CPU frequency table. 400 + /// 401 + /// ``` 402 + /// use kernel::cpufreq::{ETERNAL_LATENCY_NS, Policy}; 403 + /// 404 + /// fn update_policy(policy: &mut Policy) { 405 + /// policy 406 + /// .set_dvfs_possible_from_any_cpu(true) 407 + /// .set_fast_switch_possible(true) 408 + /// .set_transition_latency_ns(ETERNAL_LATENCY_NS); 409 + /// 410 + /// pr_info!("The policy details are: {:?}\n", (policy.cpu(), policy.cur())); 411 + /// } 412 + /// ``` 413 + #[repr(transparent)] 414 + pub struct Policy(Opaque<bindings::cpufreq_policy>); 415 + 416 + impl Policy { 417 + /// Creates a reference to an existing `struct cpufreq_policy` pointer. 418 + /// 419 + /// # Safety 420 + /// 421 + /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime 422 + /// of the returned reference. 423 + #[inline] 424 + pub unsafe fn from_raw<'a>(ptr: *const bindings::cpufreq_policy) -> &'a Self { 425 + // SAFETY: Guaranteed by the safety requirements of the function. 426 + // 427 + // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the 428 + // lifetime of the returned reference. 429 + unsafe { &*ptr.cast() } 430 + } 431 + 432 + /// Creates a mutable reference to an existing `struct cpufreq_policy` pointer. 433 + /// 434 + /// # Safety 435 + /// 436 + /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime 437 + /// of the returned reference. 438 + #[inline] 439 + pub unsafe fn from_raw_mut<'a>(ptr: *mut bindings::cpufreq_policy) -> &'a mut Self { 440 + // SAFETY: Guaranteed by the safety requirements of the function. 441 + // 442 + // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the 443 + // lifetime of the returned reference. 444 + unsafe { &mut *ptr.cast() } 445 + } 446 + 447 + /// Returns a raw mutable pointer to the C `struct cpufreq_policy`. 448 + #[inline] 449 + fn as_raw(&self) -> *mut bindings::cpufreq_policy { 450 + let this: *const Self = self; 451 + this.cast_mut().cast() 452 + } 453 + 454 + #[inline] 455 + fn as_ref(&self) -> &bindings::cpufreq_policy { 456 + // SAFETY: By the type invariant, the pointer stored in `self` is valid. 457 + unsafe { &*self.as_raw() } 458 + } 459 + 460 + #[inline] 461 + fn as_mut_ref(&mut self) -> &mut bindings::cpufreq_policy { 462 + // SAFETY: By the type invariant, the pointer stored in `self` is valid. 463 + unsafe { &mut *self.as_raw() } 464 + } 465 + 466 + /// Returns the primary CPU for the [`Policy`]. 467 + #[inline] 468 + pub fn cpu(&self) -> u32 { 469 + self.as_ref().cpu 470 + } 471 + 472 + /// Returns the minimum frequency for the [`Policy`]. 473 + #[inline] 474 + pub fn min(&self) -> Hertz { 475 + Hertz::from_khz(self.as_ref().min as usize) 476 + } 477 + 478 + /// Set the minimum frequency for the [`Policy`]. 479 + #[inline] 480 + pub fn set_min(&mut self, min: Hertz) -> &mut Self { 481 + self.as_mut_ref().min = min.as_khz() as u32; 482 + self 483 + } 484 + 485 + /// Returns the maximum frequency for the [`Policy`]. 486 + #[inline] 487 + pub fn max(&self) -> Hertz { 488 + Hertz::from_khz(self.as_ref().max as usize) 489 + } 490 + 491 + /// Set the maximum frequency for the [`Policy`]. 492 + #[inline] 493 + pub fn set_max(&mut self, max: Hertz) -> &mut Self { 494 + self.as_mut_ref().max = max.as_khz() as u32; 495 + self 496 + } 497 + 498 + /// Returns the current frequency for the [`Policy`]. 499 + #[inline] 500 + pub fn cur(&self) -> Hertz { 501 + Hertz::from_khz(self.as_ref().cur as usize) 502 + } 503 + 504 + /// Returns the suspend frequency for the [`Policy`]. 505 + #[inline] 506 + pub fn suspend_freq(&self) -> Hertz { 507 + Hertz::from_khz(self.as_ref().suspend_freq as usize) 508 + } 509 + 510 + /// Sets the suspend frequency for the [`Policy`]. 511 + #[inline] 512 + pub fn set_suspend_freq(&mut self, freq: Hertz) -> &mut Self { 513 + self.as_mut_ref().suspend_freq = freq.as_khz() as u32; 514 + self 515 + } 516 + 517 + /// Provides a wrapper to the generic suspend routine. 518 + #[inline] 519 + pub fn generic_suspend(&mut self) -> Result { 520 + // SAFETY: By the type invariant, the pointer stored in `self` is valid. 521 + to_result(unsafe { bindings::cpufreq_generic_suspend(self.as_mut_ref()) }) 522 + } 523 + 524 + /// Provides a wrapper to the generic get routine. 525 + #[inline] 526 + pub fn generic_get(&self) -> Result<u32> { 527 + // SAFETY: By the type invariant, the pointer stored in `self` is valid. 528 + Ok(unsafe { bindings::cpufreq_generic_get(self.cpu()) }) 529 + } 530 + 531 + /// Provides a wrapper to the register with energy model using the OPP core. 532 + #[cfg(CONFIG_PM_OPP)] 533 + #[inline] 534 + pub fn register_em_opp(&mut self) { 535 + // SAFETY: By the type invariant, the pointer stored in `self` is valid. 536 + unsafe { bindings::cpufreq_register_em_with_opp(self.as_mut_ref()) }; 537 + } 538 + 539 + /// Gets [`cpumask::Cpumask`] for a cpufreq [`Policy`]. 540 + #[inline] 541 + pub fn cpus(&mut self) -> &mut cpumask::Cpumask { 542 + // SAFETY: The pointer to `cpus` is valid for writing and remains valid for the lifetime of 543 + // the returned reference. 544 + unsafe { cpumask::CpumaskVar::as_mut_ref(&mut self.as_mut_ref().cpus) } 545 + } 546 + 547 + /// Sets clock for the [`Policy`]. 548 + /// 549 + /// # Safety 550 + /// 551 + /// The caller must guarantee that the returned [`Clk`] is not dropped while it is getting used 552 + /// by the C code. 553 + #[cfg(CONFIG_COMMON_CLK)] 554 + pub unsafe fn set_clk(&mut self, dev: &Device, name: Option<&CStr>) -> Result<Clk> { 555 + let clk = Clk::get(dev, name)?; 556 + self.as_mut_ref().clk = clk.as_raw(); 557 + Ok(clk) 558 + } 559 + 560 + /// Allows / disallows frequency switching code to run on any CPU. 561 + #[inline] 562 + pub fn set_dvfs_possible_from_any_cpu(&mut self, val: bool) -> &mut Self { 563 + self.as_mut_ref().dvfs_possible_from_any_cpu = val; 564 + self 565 + } 566 + 567 + /// Returns if fast switching of frequencies is possible or not. 568 + #[inline] 569 + pub fn fast_switch_possible(&self) -> bool { 570 + self.as_ref().fast_switch_possible 571 + } 572 + 573 + /// Enables / disables fast frequency switching. 574 + #[inline] 575 + pub fn set_fast_switch_possible(&mut self, val: bool) -> &mut Self { 576 + self.as_mut_ref().fast_switch_possible = val; 577 + self 578 + } 579 + 580 + /// Sets transition latency (in nanoseconds) for the [`Policy`]. 581 + #[inline] 582 + pub fn set_transition_latency_ns(&mut self, latency_ns: u32) -> &mut Self { 583 + self.as_mut_ref().cpuinfo.transition_latency = latency_ns; 584 + self 585 + } 586 + 587 + /// Sets cpuinfo `min_freq`. 588 + #[inline] 589 + pub fn set_cpuinfo_min_freq(&mut self, min_freq: Hertz) -> &mut Self { 590 + self.as_mut_ref().cpuinfo.min_freq = min_freq.as_khz() as u32; 591 + self 592 + } 593 + 594 + /// Sets cpuinfo `max_freq`. 595 + #[inline] 596 + pub fn set_cpuinfo_max_freq(&mut self, max_freq: Hertz) -> &mut Self { 597 + self.as_mut_ref().cpuinfo.max_freq = max_freq.as_khz() as u32; 598 + self 599 + } 600 + 601 + /// Set `transition_delay_us`, i.e. the minimum time between successive frequency change 602 + /// requests. 603 + #[inline] 604 + pub fn set_transition_delay_us(&mut self, transition_delay_us: u32) -> &mut Self { 605 + self.as_mut_ref().transition_delay_us = transition_delay_us; 606 + self 607 + } 608 + 609 + /// Returns reference to the CPU frequency [`Table`] for the [`Policy`]. 610 + pub fn freq_table(&self) -> Result<&Table> { 611 + if self.as_ref().freq_table.is_null() { 612 + return Err(EINVAL); 613 + } 614 + 615 + // SAFETY: The `freq_table` is guaranteed to be valid for reading and remains valid for the 616 + // lifetime of the returned reference. 617 + Ok(unsafe { Table::from_raw(self.as_ref().freq_table) }) 618 + } 619 + 620 + /// Sets the CPU frequency [`Table`] for the [`Policy`]. 621 + /// 622 + /// # Safety 623 + /// 624 + /// The caller must guarantee that the [`Table`] is not dropped while it is getting used by the 625 + /// C code. 626 + #[inline] 627 + pub unsafe fn set_freq_table(&mut self, table: &Table) -> &mut Self { 628 + self.as_mut_ref().freq_table = table.as_raw(); 629 + self 630 + } 631 + 632 + /// Returns the [`Policy`]'s private data. 633 + pub fn data<T: ForeignOwnable>(&mut self) -> Option<<T>::Borrowed<'_>> { 634 + if self.as_ref().driver_data.is_null() { 635 + None 636 + } else { 637 + // SAFETY: The data is earlier set from [`set_data`]. 638 + Some(unsafe { T::borrow(self.as_ref().driver_data) }) 639 + } 640 + } 641 + 642 + /// Sets the private data of the [`Policy`] using a foreign-ownable wrapper. 643 + /// 644 + /// # Errors 645 + /// 646 + /// Returns `EBUSY` if private data is already set. 647 + fn set_data<T: ForeignOwnable>(&mut self, data: T) -> Result { 648 + if self.as_ref().driver_data.is_null() { 649 + // Transfer the ownership of the data to the foreign interface. 650 + self.as_mut_ref().driver_data = <T as ForeignOwnable>::into_foreign(data) as _; 651 + Ok(()) 652 + } else { 653 + Err(EBUSY) 654 + } 655 + } 656 + 657 + /// Clears and returns ownership of the private data. 658 + fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> { 659 + if self.as_ref().driver_data.is_null() { 660 + None 661 + } else { 662 + let data = Some( 663 + // SAFETY: The data is earlier set by us from [`set_data`]. It is safe to take 664 + // back the ownership of the data from the foreign interface. 665 + unsafe { <T as ForeignOwnable>::from_foreign(self.as_ref().driver_data) }, 666 + ); 667 + self.as_mut_ref().driver_data = ptr::null_mut(); 668 + data 669 + } 670 + } 671 + } 672 + 673 + /// CPU frequency policy created from a CPU number. 674 + /// 675 + /// This struct represents the CPU frequency policy obtained for a specific CPU, providing safe 676 + /// access to the underlying `cpufreq_policy` and ensuring proper cleanup when the `PolicyCpu` is 677 + /// dropped. 678 + struct PolicyCpu<'a>(&'a mut Policy); 679 + 680 + impl<'a> PolicyCpu<'a> { 681 + fn from_cpu(cpu: u32) -> Result<Self> { 682 + // SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU. 683 + let ptr = from_err_ptr(unsafe { bindings::cpufreq_cpu_get(cpu) })?; 684 + 685 + Ok(Self( 686 + // SAFETY: The `ptr` is guaranteed to be valid and remains valid for the lifetime of 687 + // the returned reference. 688 + unsafe { Policy::from_raw_mut(ptr) }, 689 + )) 690 + } 691 + } 692 + 693 + impl<'a> Deref for PolicyCpu<'a> { 694 + type Target = Policy; 695 + 696 + fn deref(&self) -> &Self::Target { 697 + self.0 698 + } 699 + } 700 + 701 + impl<'a> DerefMut for PolicyCpu<'a> { 702 + fn deref_mut(&mut self) -> &mut Policy { 703 + self.0 704 + } 705 + } 706 + 707 + impl<'a> Drop for PolicyCpu<'a> { 708 + fn drop(&mut self) { 709 + // SAFETY: The underlying pointer is guaranteed to be valid for the lifetime of `self`. 710 + unsafe { bindings::cpufreq_cpu_put(self.0.as_raw()) }; 711 + } 712 + } 713 + 714 + /// CPU frequency driver. 715 + /// 716 + /// Implement this trait to provide a CPU frequency driver and its callbacks. 717 + /// 718 + /// Reference: <https://docs.kernel.org/cpu-freq/cpu-drivers.html> 719 + #[vtable] 720 + pub trait Driver { 721 + /// Driver's name. 722 + const NAME: &'static CStr; 723 + 724 + /// Driver's flags. 725 + const FLAGS: u16; 726 + 727 + /// Boost support. 728 + const BOOST_ENABLED: bool; 729 + 730 + /// Policy specific data. 731 + /// 732 + /// Require that `PData` implements `ForeignOwnable`. We guarantee to never move the underlying 733 + /// wrapped data structure. 734 + type PData: ForeignOwnable; 735 + 736 + /// Driver's `init` callback. 737 + fn init(policy: &mut Policy) -> Result<Self::PData>; 738 + 739 + /// Driver's `exit` callback. 740 + fn exit(_policy: &mut Policy, _data: Option<Self::PData>) -> Result { 741 + build_error!(VTABLE_DEFAULT_ERROR) 742 + } 743 + 744 + /// Driver's `online` callback. 745 + fn online(_policy: &mut Policy) -> Result { 746 + build_error!(VTABLE_DEFAULT_ERROR) 747 + } 748 + 749 + /// Driver's `offline` callback. 750 + fn offline(_policy: &mut Policy) -> Result { 751 + build_error!(VTABLE_DEFAULT_ERROR) 752 + } 753 + 754 + /// Driver's `suspend` callback. 755 + fn suspend(_policy: &mut Policy) -> Result { 756 + build_error!(VTABLE_DEFAULT_ERROR) 757 + } 758 + 759 + /// Driver's `resume` callback. 760 + fn resume(_policy: &mut Policy) -> Result { 761 + build_error!(VTABLE_DEFAULT_ERROR) 762 + } 763 + 764 + /// Driver's `ready` callback. 765 + fn ready(_policy: &mut Policy) { 766 + build_error!(VTABLE_DEFAULT_ERROR) 767 + } 768 + 769 + /// Driver's `verify` callback. 770 + fn verify(data: &mut PolicyData) -> Result; 771 + 772 + /// Driver's `setpolicy` callback. 773 + fn setpolicy(_policy: &mut Policy) -> Result { 774 + build_error!(VTABLE_DEFAULT_ERROR) 775 + } 776 + 777 + /// Driver's `target` callback. 778 + fn target(_policy: &mut Policy, _target_freq: u32, _relation: Relation) -> Result { 779 + build_error!(VTABLE_DEFAULT_ERROR) 780 + } 781 + 782 + /// Driver's `target_index` callback. 783 + fn target_index(_policy: &mut Policy, _index: TableIndex) -> Result { 784 + build_error!(VTABLE_DEFAULT_ERROR) 785 + } 786 + 787 + /// Driver's `fast_switch` callback. 788 + fn fast_switch(_policy: &mut Policy, _target_freq: u32) -> u32 { 789 + build_error!(VTABLE_DEFAULT_ERROR) 790 + } 791 + 792 + /// Driver's `adjust_perf` callback. 793 + fn adjust_perf(_policy: &mut Policy, _min_perf: usize, _target_perf: usize, _capacity: usize) { 794 + build_error!(VTABLE_DEFAULT_ERROR) 795 + } 796 + 797 + /// Driver's `get_intermediate` callback. 798 + fn get_intermediate(_policy: &mut Policy, _index: TableIndex) -> u32 { 799 + build_error!(VTABLE_DEFAULT_ERROR) 800 + } 801 + 802 + /// Driver's `target_intermediate` callback. 803 + fn target_intermediate(_policy: &mut Policy, _index: TableIndex) -> Result { 804 + build_error!(VTABLE_DEFAULT_ERROR) 805 + } 806 + 807 + /// Driver's `get` callback. 808 + fn get(_policy: &mut Policy) -> Result<u32> { 809 + build_error!(VTABLE_DEFAULT_ERROR) 810 + } 811 + 812 + /// Driver's `update_limits` callback. 813 + fn update_limits(_policy: &mut Policy) { 814 + build_error!(VTABLE_DEFAULT_ERROR) 815 + } 816 + 817 + /// Driver's `bios_limit` callback. 818 + fn bios_limit(_policy: &mut Policy, _limit: &mut u32) -> Result { 819 + build_error!(VTABLE_DEFAULT_ERROR) 820 + } 821 + 822 + /// Driver's `set_boost` callback. 823 + fn set_boost(_policy: &mut Policy, _state: i32) -> Result { 824 + build_error!(VTABLE_DEFAULT_ERROR) 825 + } 826 + 827 + /// Driver's `register_em` callback. 828 + fn register_em(_policy: &mut Policy) { 829 + build_error!(VTABLE_DEFAULT_ERROR) 830 + } 831 + } 832 + 833 + /// CPU frequency driver Registration. 834 + /// 835 + /// ## Examples 836 + /// 837 + /// The following example demonstrates how to register a cpufreq driver. 838 + /// 839 + /// ``` 840 + /// use kernel::{ 841 + /// cpufreq, 842 + /// c_str, 843 + /// device::{Core, Device}, 844 + /// macros::vtable, 845 + /// of, platform, 846 + /// sync::Arc, 847 + /// }; 848 + /// struct SampleDevice; 849 + /// 850 + /// #[derive(Default)] 851 + /// struct SampleDriver; 852 + /// 853 + /// #[vtable] 854 + /// impl cpufreq::Driver for SampleDriver { 855 + /// const NAME: &'static CStr = c_str!("cpufreq-sample"); 856 + /// const FLAGS: u16 = cpufreq::flags::NEED_INITIAL_FREQ_CHECK | cpufreq::flags::IS_COOLING_DEV; 857 + /// const BOOST_ENABLED: bool = true; 858 + /// 859 + /// type PData = Arc<SampleDevice>; 860 + /// 861 + /// fn init(policy: &mut cpufreq::Policy) -> Result<Self::PData> { 862 + /// // Initialize here 863 + /// Ok(Arc::new(SampleDevice, GFP_KERNEL)?) 864 + /// } 865 + /// 866 + /// fn exit(_policy: &mut cpufreq::Policy, _data: Option<Self::PData>) -> Result { 867 + /// Ok(()) 868 + /// } 869 + /// 870 + /// fn suspend(policy: &mut cpufreq::Policy) -> Result { 871 + /// policy.generic_suspend() 872 + /// } 873 + /// 874 + /// fn verify(data: &mut cpufreq::PolicyData) -> Result { 875 + /// data.generic_verify() 876 + /// } 877 + /// 878 + /// fn target_index(policy: &mut cpufreq::Policy, index: cpufreq::TableIndex) -> Result { 879 + /// // Update CPU frequency 880 + /// Ok(()) 881 + /// } 882 + /// 883 + /// fn get(policy: &mut cpufreq::Policy) -> Result<u32> { 884 + /// policy.generic_get() 885 + /// } 886 + /// } 887 + /// 888 + /// impl platform::Driver for SampleDriver { 889 + /// type IdInfo = (); 890 + /// const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None; 891 + /// 892 + /// fn probe( 893 + /// pdev: &platform::Device<Core>, 894 + /// _id_info: Option<&Self::IdInfo>, 895 + /// ) -> Result<Pin<KBox<Self>>> { 896 + /// cpufreq::Registration::<SampleDriver>::new_foreign_owned(pdev.as_ref())?; 897 + /// Ok(KBox::new(Self {}, GFP_KERNEL)?.into()) 898 + /// } 899 + /// } 900 + /// ``` 901 + #[repr(transparent)] 902 + pub struct Registration<T: Driver>(KBox<UnsafeCell<bindings::cpufreq_driver>>, PhantomData<T>); 903 + 904 + /// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between threads 905 + /// or CPUs, so it is safe to share it. 906 + unsafe impl<T: Driver> Sync for Registration<T> {} 907 + 908 + #[allow(clippy::non_send_fields_in_send_ty)] 909 + /// SAFETY: Registration with and unregistration from the cpufreq subsystem can happen from any 910 + /// thread. 911 + unsafe impl<T: Driver> Send for Registration<T> {} 912 + 913 + impl<T: Driver> Registration<T> { 914 + const VTABLE: bindings::cpufreq_driver = bindings::cpufreq_driver { 915 + name: Self::copy_name(T::NAME), 916 + boost_enabled: T::BOOST_ENABLED, 917 + flags: T::FLAGS, 918 + 919 + // Initialize mandatory callbacks. 920 + init: Some(Self::init_callback), 921 + verify: Some(Self::verify_callback), 922 + 923 + // Initialize optional callbacks based on the traits of `T`. 924 + setpolicy: if T::HAS_SETPOLICY { 925 + Some(Self::setpolicy_callback) 926 + } else { 927 + None 928 + }, 929 + target: if T::HAS_TARGET { 930 + Some(Self::target_callback) 931 + } else { 932 + None 933 + }, 934 + target_index: if T::HAS_TARGET_INDEX { 935 + Some(Self::target_index_callback) 936 + } else { 937 + None 938 + }, 939 + fast_switch: if T::HAS_FAST_SWITCH { 940 + Some(Self::fast_switch_callback) 941 + } else { 942 + None 943 + }, 944 + adjust_perf: if T::HAS_ADJUST_PERF { 945 + Some(Self::adjust_perf_callback) 946 + } else { 947 + None 948 + }, 949 + get_intermediate: if T::HAS_GET_INTERMEDIATE { 950 + Some(Self::get_intermediate_callback) 951 + } else { 952 + None 953 + }, 954 + target_intermediate: if T::HAS_TARGET_INTERMEDIATE { 955 + Some(Self::target_intermediate_callback) 956 + } else { 957 + None 958 + }, 959 + get: if T::HAS_GET { 960 + Some(Self::get_callback) 961 + } else { 962 + None 963 + }, 964 + update_limits: if T::HAS_UPDATE_LIMITS { 965 + Some(Self::update_limits_callback) 966 + } else { 967 + None 968 + }, 969 + bios_limit: if T::HAS_BIOS_LIMIT { 970 + Some(Self::bios_limit_callback) 971 + } else { 972 + None 973 + }, 974 + online: if T::HAS_ONLINE { 975 + Some(Self::online_callback) 976 + } else { 977 + None 978 + }, 979 + offline: if T::HAS_OFFLINE { 980 + Some(Self::offline_callback) 981 + } else { 982 + None 983 + }, 984 + exit: if T::HAS_EXIT { 985 + Some(Self::exit_callback) 986 + } else { 987 + None 988 + }, 989 + suspend: if T::HAS_SUSPEND { 990 + Some(Self::suspend_callback) 991 + } else { 992 + None 993 + }, 994 + resume: if T::HAS_RESUME { 995 + Some(Self::resume_callback) 996 + } else { 997 + None 998 + }, 999 + ready: if T::HAS_READY { 1000 + Some(Self::ready_callback) 1001 + } else { 1002 + None 1003 + }, 1004 + set_boost: if T::HAS_SET_BOOST { 1005 + Some(Self::set_boost_callback) 1006 + } else { 1007 + None 1008 + }, 1009 + register_em: if T::HAS_REGISTER_EM { 1010 + Some(Self::register_em_callback) 1011 + } else { 1012 + None 1013 + }, 1014 + // SAFETY: All zeros is a valid value for `bindings::cpufreq_driver`. 1015 + ..unsafe { MaybeUninit::zeroed().assume_init() } 1016 + }; 1017 + 1018 + const fn copy_name(name: &'static CStr) -> [c_char; CPUFREQ_NAME_LEN] { 1019 + let src = name.as_bytes_with_nul(); 1020 + let mut dst = [0; CPUFREQ_NAME_LEN]; 1021 + 1022 + build_assert!(src.len() <= CPUFREQ_NAME_LEN); 1023 + 1024 + let mut i = 0; 1025 + while i < src.len() { 1026 + dst[i] = src[i]; 1027 + i += 1; 1028 + } 1029 + 1030 + dst 1031 + } 1032 + 1033 + /// Registers a CPU frequency driver with the cpufreq core. 1034 + pub fn new() -> Result<Self> { 1035 + // We can't use `&Self::VTABLE` directly because the cpufreq core modifies some fields in 1036 + // the C `struct cpufreq_driver`, which requires a mutable reference. 1037 + let mut drv = KBox::new(UnsafeCell::new(Self::VTABLE), GFP_KERNEL)?; 1038 + 1039 + // SAFETY: `drv` is guaranteed to be valid for the lifetime of `Registration`. 1040 + to_result(unsafe { bindings::cpufreq_register_driver(drv.get_mut()) })?; 1041 + 1042 + Ok(Self(drv, PhantomData)) 1043 + } 1044 + 1045 + /// Same as [`Registration::new`], but does not return a [`Registration`] instance. 1046 + /// 1047 + /// Instead the [`Registration`] is owned by [`Devres`] and will be revoked / dropped, once the 1048 + /// device is detached. 1049 + pub fn new_foreign_owned(dev: &Device<Bound>) -> Result { 1050 + Devres::new_foreign_owned(dev, Self::new()?, GFP_KERNEL) 1051 + } 1052 + } 1053 + 1054 + /// CPU frequency driver callbacks. 1055 + impl<T: Driver> Registration<T> { 1056 + /// Driver's `init` callback. 1057 + /// 1058 + /// SAFETY: Called from C. Inputs must be valid pointers. 1059 + extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int { 1060 + from_result(|| { 1061 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1062 + // lifetime of `policy`. 1063 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1064 + 1065 + let data = T::init(policy)?; 1066 + policy.set_data(data)?; 1067 + Ok(0) 1068 + }) 1069 + } 1070 + 1071 + /// Driver's `exit` callback. 1072 + /// 1073 + /// SAFETY: Called from C. Inputs must be valid pointers. 1074 + extern "C" fn exit_callback(ptr: *mut bindings::cpufreq_policy) { 1075 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1076 + // lifetime of `policy`. 1077 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1078 + 1079 + let data = policy.clear_data(); 1080 + let _ = T::exit(policy, data); 1081 + } 1082 + 1083 + /// Driver's `online` callback. 1084 + /// 1085 + /// SAFETY: Called from C. Inputs must be valid pointers. 1086 + extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int { 1087 + from_result(|| { 1088 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1089 + // lifetime of `policy`. 1090 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1091 + T::online(policy).map(|()| 0) 1092 + }) 1093 + } 1094 + 1095 + /// Driver's `offline` callback. 1096 + /// 1097 + /// SAFETY: Called from C. Inputs must be valid pointers. 1098 + extern "C" fn offline_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int { 1099 + from_result(|| { 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 + T::offline(policy).map(|()| 0) 1104 + }) 1105 + } 1106 + 1107 + /// Driver's `suspend` callback. 1108 + /// 1109 + /// SAFETY: Called from C. Inputs must be valid pointers. 1110 + extern "C" fn suspend_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int { 1111 + from_result(|| { 1112 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1113 + // lifetime of `policy`. 1114 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1115 + T::suspend(policy).map(|()| 0) 1116 + }) 1117 + } 1118 + 1119 + /// Driver's `resume` callback. 1120 + /// 1121 + /// SAFETY: Called from C. Inputs must be valid pointers. 1122 + extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int { 1123 + from_result(|| { 1124 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1125 + // lifetime of `policy`. 1126 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1127 + T::resume(policy).map(|()| 0) 1128 + }) 1129 + } 1130 + 1131 + /// Driver's `ready` callback. 1132 + /// 1133 + /// SAFETY: Called from C. Inputs must be valid pointers. 1134 + extern "C" fn ready_callback(ptr: *mut bindings::cpufreq_policy) { 1135 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1136 + // lifetime of `policy`. 1137 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1138 + T::ready(policy); 1139 + } 1140 + 1141 + /// Driver's `verify` callback. 1142 + /// 1143 + /// SAFETY: Called from C. Inputs must be valid pointers. 1144 + extern "C" fn verify_callback(ptr: *mut bindings::cpufreq_policy_data) -> kernel::ffi::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 data = unsafe { PolicyData::from_raw_mut(ptr) }; 1149 + T::verify(data).map(|()| 0) 1150 + }) 1151 + } 1152 + 1153 + /// Driver's `setpolicy` callback. 1154 + /// 1155 + /// SAFETY: Called from C. Inputs must be valid pointers. 1156 + extern "C" fn setpolicy_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int { 1157 + from_result(|| { 1158 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1159 + // lifetime of `policy`. 1160 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1161 + T::setpolicy(policy).map(|()| 0) 1162 + }) 1163 + } 1164 + 1165 + /// Driver's `target` callback. 1166 + /// 1167 + /// SAFETY: Called from C. Inputs must be valid pointers. 1168 + extern "C" fn target_callback( 1169 + ptr: *mut bindings::cpufreq_policy, 1170 + target_freq: u32, 1171 + relation: u32, 1172 + ) -> kernel::ffi::c_int { 1173 + from_result(|| { 1174 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1175 + // lifetime of `policy`. 1176 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1177 + T::target(policy, target_freq, Relation::new(relation)?).map(|()| 0) 1178 + }) 1179 + } 1180 + 1181 + /// Driver's `target_index` callback. 1182 + /// 1183 + /// SAFETY: Called from C. Inputs must be valid pointers. 1184 + extern "C" fn target_index_callback( 1185 + ptr: *mut bindings::cpufreq_policy, 1186 + index: u32, 1187 + ) -> kernel::ffi::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 policy = unsafe { Policy::from_raw_mut(ptr) }; 1192 + 1193 + // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the 1194 + // frequency table. 1195 + let index = unsafe { TableIndex::new(index as usize) }; 1196 + 1197 + T::target_index(policy, index).map(|()| 0) 1198 + }) 1199 + } 1200 + 1201 + /// Driver's `fast_switch` callback. 1202 + /// 1203 + /// SAFETY: Called from C. Inputs must be valid pointers. 1204 + extern "C" fn fast_switch_callback( 1205 + ptr: *mut bindings::cpufreq_policy, 1206 + target_freq: u32, 1207 + ) -> kernel::ffi::c_uint { 1208 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1209 + // lifetime of `policy`. 1210 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1211 + T::fast_switch(policy, target_freq) 1212 + } 1213 + 1214 + /// Driver's `adjust_perf` callback. 1215 + extern "C" fn adjust_perf_callback( 1216 + cpu: u32, 1217 + min_perf: usize, 1218 + target_perf: usize, 1219 + capacity: usize, 1220 + ) { 1221 + if let Ok(mut policy) = PolicyCpu::from_cpu(cpu) { 1222 + T::adjust_perf(&mut policy, min_perf, target_perf, capacity); 1223 + } 1224 + } 1225 + 1226 + /// Driver's `get_intermediate` callback. 1227 + /// 1228 + /// SAFETY: Called from C. Inputs must be valid pointers. 1229 + extern "C" fn get_intermediate_callback( 1230 + ptr: *mut bindings::cpufreq_policy, 1231 + index: u32, 1232 + ) -> kernel::ffi::c_uint { 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 + 1237 + // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the 1238 + // frequency table. 1239 + let index = unsafe { TableIndex::new(index as usize) }; 1240 + 1241 + T::get_intermediate(policy, index) 1242 + } 1243 + 1244 + /// Driver's `target_intermediate` callback. 1245 + /// 1246 + /// SAFETY: Called from C. Inputs must be valid pointers. 1247 + extern "C" fn target_intermediate_callback( 1248 + ptr: *mut bindings::cpufreq_policy, 1249 + index: u32, 1250 + ) -> kernel::ffi::c_int { 1251 + from_result(|| { 1252 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1253 + // lifetime of `policy`. 1254 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1255 + 1256 + // SAFETY: The C code guarantees that `index` corresponds to a valid entry in the 1257 + // frequency table. 1258 + let index = unsafe { TableIndex::new(index as usize) }; 1259 + 1260 + T::target_intermediate(policy, index).map(|()| 0) 1261 + }) 1262 + } 1263 + 1264 + /// Driver's `get` callback. 1265 + extern "C" fn get_callback(cpu: u32) -> kernel::ffi::c_uint { 1266 + PolicyCpu::from_cpu(cpu).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f)) 1267 + } 1268 + 1269 + /// Driver's `update_limit` callback. 1270 + extern "C" fn update_limits_callback(ptr: *mut bindings::cpufreq_policy) { 1271 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1272 + // lifetime of `policy`. 1273 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1274 + T::update_limits(policy); 1275 + } 1276 + 1277 + /// Driver's `bios_limit` callback. 1278 + /// 1279 + /// SAFETY: Called from C. Inputs must be valid pointers. 1280 + extern "C" fn bios_limit_callback(cpu: i32, limit: *mut u32) -> kernel::ffi::c_int { 1281 + from_result(|| { 1282 + let mut policy = PolicyCpu::from_cpu(cpu as u32)?; 1283 + 1284 + // SAFETY: `limit` is guaranteed by the C code to be valid. 1285 + T::bios_limit(&mut policy, &mut (unsafe { *limit })).map(|()| 0) 1286 + }) 1287 + } 1288 + 1289 + /// Driver's `set_boost` callback. 1290 + /// 1291 + /// SAFETY: Called from C. Inputs must be valid pointers. 1292 + extern "C" fn set_boost_callback( 1293 + ptr: *mut bindings::cpufreq_policy, 1294 + state: i32, 1295 + ) -> kernel::ffi::c_int { 1296 + from_result(|| { 1297 + // SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the 1298 + // lifetime of `policy`. 1299 + let policy = unsafe { Policy::from_raw_mut(ptr) }; 1300 + T::set_boost(policy, state).map(|()| 0) 1301 + }) 1302 + } 1303 + 1304 + /// Driver's `register_em` callback. 1305 + /// 1306 + /// SAFETY: Called from C. Inputs must be valid pointers. 1307 + extern "C" fn register_em_callback(ptr: *mut bindings::cpufreq_policy) { 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 + T::register_em(policy); 1312 + } 1313 + } 1314 + 1315 + impl<T: Driver> Drop for Registration<T> { 1316 + /// Unregisters with the cpufreq core. 1317 + fn drop(&mut self) { 1318 + // SAFETY: `self.0` is guaranteed to be valid for the lifetime of `Registration`. 1319 + unsafe { bindings::cpufreq_unregister_driver(self.0.get_mut()) }; 1320 + } 1321 + }
+330
rust/kernel/cpumask.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! CPU Mask abstractions. 4 + //! 5 + //! C header: [`include/linux/cpumask.h`](srctree/include/linux/cpumask.h) 6 + 7 + use crate::{ 8 + alloc::{AllocError, Flags}, 9 + prelude::*, 10 + types::Opaque, 11 + }; 12 + 13 + #[cfg(CONFIG_CPUMASK_OFFSTACK)] 14 + use core::ptr::{self, NonNull}; 15 + 16 + #[cfg(not(CONFIG_CPUMASK_OFFSTACK))] 17 + use core::mem::MaybeUninit; 18 + 19 + use core::ops::{Deref, DerefMut}; 20 + 21 + /// A CPU Mask. 22 + /// 23 + /// Rust abstraction for the C `struct cpumask`. 24 + /// 25 + /// # Invariants 26 + /// 27 + /// A [`Cpumask`] instance always corresponds to a valid C `struct cpumask`. 28 + /// 29 + /// The callers must ensure that the `struct cpumask` is valid for access and 30 + /// remains valid for the lifetime of the returned reference. 31 + /// 32 + /// ## Examples 33 + /// 34 + /// The following example demonstrates how to update a [`Cpumask`]. 35 + /// 36 + /// ``` 37 + /// use kernel::bindings; 38 + /// use kernel::cpumask::Cpumask; 39 + /// 40 + /// fn set_clear_cpu(ptr: *mut bindings::cpumask, set_cpu: u32, clear_cpu: i32) { 41 + /// // SAFETY: The `ptr` is valid for writing and remains valid for the lifetime of the 42 + /// // returned reference. 43 + /// let mask = unsafe { Cpumask::as_mut_ref(ptr) }; 44 + /// 45 + /// mask.set(set_cpu); 46 + /// mask.clear(clear_cpu); 47 + /// } 48 + /// ``` 49 + #[repr(transparent)] 50 + pub struct Cpumask(Opaque<bindings::cpumask>); 51 + 52 + impl Cpumask { 53 + /// Creates a mutable reference to an existing `struct cpumask` pointer. 54 + /// 55 + /// # Safety 56 + /// 57 + /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime 58 + /// of the returned reference. 59 + pub unsafe fn as_mut_ref<'a>(ptr: *mut bindings::cpumask) -> &'a mut Self { 60 + // SAFETY: Guaranteed by the safety requirements of the function. 61 + // 62 + // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the 63 + // lifetime of the returned reference. 64 + unsafe { &mut *ptr.cast() } 65 + } 66 + 67 + /// Creates a reference to an existing `struct cpumask` pointer. 68 + /// 69 + /// # Safety 70 + /// 71 + /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime 72 + /// of the returned reference. 73 + pub unsafe fn as_ref<'a>(ptr: *const bindings::cpumask) -> &'a Self { 74 + // SAFETY: Guaranteed by the safety requirements of the function. 75 + // 76 + // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the 77 + // lifetime of the returned reference. 78 + unsafe { &*ptr.cast() } 79 + } 80 + 81 + /// Obtain the raw `struct cpumask` pointer. 82 + pub fn as_raw(&self) -> *mut bindings::cpumask { 83 + let this: *const Self = self; 84 + this.cast_mut().cast() 85 + } 86 + 87 + /// Set `cpu` in the cpumask. 88 + /// 89 + /// ATTENTION: Contrary to C, this Rust `set()` method is non-atomic. 90 + /// This mismatches kernel naming convention and corresponds to the C 91 + /// function `__cpumask_set_cpu()`. 92 + #[inline] 93 + pub fn set(&mut self, cpu: u32) { 94 + // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `__cpumask_set_cpu`. 95 + unsafe { bindings::__cpumask_set_cpu(cpu, self.as_raw()) }; 96 + } 97 + 98 + /// Clear `cpu` in the cpumask. 99 + /// 100 + /// ATTENTION: Contrary to C, this Rust `clear()` method is non-atomic. 101 + /// This mismatches kernel naming convention and corresponds to the C 102 + /// function `__cpumask_clear_cpu()`. 103 + #[inline] 104 + pub fn clear(&mut self, cpu: i32) { 105 + // SAFETY: By the type invariant, `self.as_raw` is a valid argument to 106 + // `__cpumask_clear_cpu`. 107 + unsafe { bindings::__cpumask_clear_cpu(cpu, self.as_raw()) }; 108 + } 109 + 110 + /// Test `cpu` in the cpumask. 111 + /// 112 + /// Equivalent to the kernel's `cpumask_test_cpu` API. 113 + #[inline] 114 + pub fn test(&self, cpu: i32) -> bool { 115 + // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `cpumask_test_cpu`. 116 + unsafe { bindings::cpumask_test_cpu(cpu, self.as_raw()) } 117 + } 118 + 119 + /// Set all CPUs in the cpumask. 120 + /// 121 + /// Equivalent to the kernel's `cpumask_setall` API. 122 + #[inline] 123 + pub fn setall(&mut self) { 124 + // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `cpumask_setall`. 125 + unsafe { bindings::cpumask_setall(self.as_raw()) }; 126 + } 127 + 128 + /// Checks if cpumask is empty. 129 + /// 130 + /// Equivalent to the kernel's `cpumask_empty` API. 131 + #[inline] 132 + pub fn empty(&self) -> bool { 133 + // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `cpumask_empty`. 134 + unsafe { bindings::cpumask_empty(self.as_raw()) } 135 + } 136 + 137 + /// Checks if cpumask is full. 138 + /// 139 + /// Equivalent to the kernel's `cpumask_full` API. 140 + #[inline] 141 + pub fn full(&self) -> bool { 142 + // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `cpumask_full`. 143 + unsafe { bindings::cpumask_full(self.as_raw()) } 144 + } 145 + 146 + /// Get weight of the cpumask. 147 + /// 148 + /// Equivalent to the kernel's `cpumask_weight` API. 149 + #[inline] 150 + pub fn weight(&self) -> u32 { 151 + // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `cpumask_weight`. 152 + unsafe { bindings::cpumask_weight(self.as_raw()) } 153 + } 154 + 155 + /// Copy cpumask. 156 + /// 157 + /// Equivalent to the kernel's `cpumask_copy` API. 158 + #[inline] 159 + pub fn copy(&self, dstp: &mut Self) { 160 + // SAFETY: By the type invariant, `Self::as_raw` is a valid argument to `cpumask_copy`. 161 + unsafe { bindings::cpumask_copy(dstp.as_raw(), self.as_raw()) }; 162 + } 163 + } 164 + 165 + /// A CPU Mask pointer. 166 + /// 167 + /// Rust abstraction for the C `struct cpumask_var_t`. 168 + /// 169 + /// # Invariants 170 + /// 171 + /// A [`CpumaskVar`] instance always corresponds to a valid C `struct cpumask_var_t`. 172 + /// 173 + /// The callers must ensure that the `struct cpumask_var_t` is valid for access and remains valid 174 + /// for the lifetime of [`CpumaskVar`]. 175 + /// 176 + /// ## Examples 177 + /// 178 + /// The following example demonstrates how to create and update a [`CpumaskVar`]. 179 + /// 180 + /// ``` 181 + /// use kernel::cpumask::CpumaskVar; 182 + /// 183 + /// let mut mask = CpumaskVar::new_zero(GFP_KERNEL).unwrap(); 184 + /// 185 + /// assert!(mask.empty()); 186 + /// mask.set(2); 187 + /// assert!(mask.test(2)); 188 + /// mask.set(3); 189 + /// assert!(mask.test(3)); 190 + /// assert_eq!(mask.weight(), 2); 191 + /// 192 + /// let mask2 = CpumaskVar::try_clone(&mask).unwrap(); 193 + /// assert!(mask2.test(2)); 194 + /// assert!(mask2.test(3)); 195 + /// assert_eq!(mask2.weight(), 2); 196 + /// ``` 197 + pub struct CpumaskVar { 198 + #[cfg(CONFIG_CPUMASK_OFFSTACK)] 199 + ptr: NonNull<Cpumask>, 200 + #[cfg(not(CONFIG_CPUMASK_OFFSTACK))] 201 + mask: Cpumask, 202 + } 203 + 204 + impl CpumaskVar { 205 + /// Creates a zero-initialized instance of the [`CpumaskVar`]. 206 + pub fn new_zero(_flags: Flags) -> Result<Self, AllocError> { 207 + Ok(Self { 208 + #[cfg(CONFIG_CPUMASK_OFFSTACK)] 209 + ptr: { 210 + let mut ptr: *mut bindings::cpumask = ptr::null_mut(); 211 + 212 + // SAFETY: It is safe to call this method as the reference to `ptr` is valid. 213 + // 214 + // INVARIANT: The associated memory is freed when the `CpumaskVar` goes out of 215 + // scope. 216 + unsafe { bindings::zalloc_cpumask_var(&mut ptr, _flags.as_raw()) }; 217 + NonNull::new(ptr.cast()).ok_or(AllocError)? 218 + }, 219 + 220 + #[cfg(not(CONFIG_CPUMASK_OFFSTACK))] 221 + // SAFETY: FFI type is valid to be zero-initialized. 222 + // 223 + // INVARIANT: The associated memory is freed when the `CpumaskVar` goes out of scope. 224 + mask: unsafe { core::mem::zeroed() }, 225 + }) 226 + } 227 + 228 + /// Creates an instance of the [`CpumaskVar`]. 229 + /// 230 + /// # Safety 231 + /// 232 + /// The caller must ensure that the returned [`CpumaskVar`] is properly initialized before 233 + /// getting used. 234 + pub unsafe fn new(_flags: Flags) -> Result<Self, AllocError> { 235 + Ok(Self { 236 + #[cfg(CONFIG_CPUMASK_OFFSTACK)] 237 + ptr: { 238 + let mut ptr: *mut bindings::cpumask = ptr::null_mut(); 239 + 240 + // SAFETY: It is safe to call this method as the reference to `ptr` is valid. 241 + // 242 + // INVARIANT: The associated memory is freed when the `CpumaskVar` goes out of 243 + // scope. 244 + unsafe { bindings::alloc_cpumask_var(&mut ptr, _flags.as_raw()) }; 245 + NonNull::new(ptr.cast()).ok_or(AllocError)? 246 + }, 247 + #[cfg(not(CONFIG_CPUMASK_OFFSTACK))] 248 + // SAFETY: Guaranteed by the safety requirements of the function. 249 + // 250 + // INVARIANT: The associated memory is freed when the `CpumaskVar` goes out of scope. 251 + mask: unsafe { MaybeUninit::uninit().assume_init() }, 252 + }) 253 + } 254 + 255 + /// Creates a mutable reference to an existing `struct cpumask_var_t` pointer. 256 + /// 257 + /// # Safety 258 + /// 259 + /// The caller must ensure that `ptr` is valid for writing and remains valid for the lifetime 260 + /// of the returned reference. 261 + pub unsafe fn as_mut_ref<'a>(ptr: *mut bindings::cpumask_var_t) -> &'a mut Self { 262 + // SAFETY: Guaranteed by the safety requirements of the function. 263 + // 264 + // INVARIANT: The caller ensures that `ptr` is valid for writing and remains valid for the 265 + // lifetime of the returned reference. 266 + unsafe { &mut *ptr.cast() } 267 + } 268 + 269 + /// Creates a reference to an existing `struct cpumask_var_t` pointer. 270 + /// 271 + /// # Safety 272 + /// 273 + /// The caller must ensure that `ptr` is valid for reading and remains valid for the lifetime 274 + /// of the returned reference. 275 + pub unsafe fn as_ref<'a>(ptr: *const bindings::cpumask_var_t) -> &'a Self { 276 + // SAFETY: Guaranteed by the safety requirements of the function. 277 + // 278 + // INVARIANT: The caller ensures that `ptr` is valid for reading and remains valid for the 279 + // lifetime of the returned reference. 280 + unsafe { &*ptr.cast() } 281 + } 282 + 283 + /// Clones cpumask. 284 + pub fn try_clone(cpumask: &Cpumask) -> Result<Self> { 285 + // SAFETY: The returned cpumask_var is initialized right after this call. 286 + let mut cpumask_var = unsafe { Self::new(GFP_KERNEL) }?; 287 + 288 + cpumask.copy(&mut cpumask_var); 289 + Ok(cpumask_var) 290 + } 291 + } 292 + 293 + // Make [`CpumaskVar`] behave like a pointer to [`Cpumask`]. 294 + impl Deref for CpumaskVar { 295 + type Target = Cpumask; 296 + 297 + #[cfg(CONFIG_CPUMASK_OFFSTACK)] 298 + fn deref(&self) -> &Self::Target { 299 + // SAFETY: The caller owns CpumaskVar, so it is safe to deref the cpumask. 300 + unsafe { &*self.ptr.as_ptr() } 301 + } 302 + 303 + #[cfg(not(CONFIG_CPUMASK_OFFSTACK))] 304 + fn deref(&self) -> &Self::Target { 305 + &self.mask 306 + } 307 + } 308 + 309 + impl DerefMut for CpumaskVar { 310 + #[cfg(CONFIG_CPUMASK_OFFSTACK)] 311 + fn deref_mut(&mut self) -> &mut Cpumask { 312 + // SAFETY: The caller owns CpumaskVar, so it is safe to deref the cpumask. 313 + unsafe { self.ptr.as_mut() } 314 + } 315 + 316 + #[cfg(not(CONFIG_CPUMASK_OFFSTACK))] 317 + fn deref_mut(&mut self) -> &mut Cpumask { 318 + &mut self.mask 319 + } 320 + } 321 + 322 + impl Drop for CpumaskVar { 323 + fn drop(&mut self) { 324 + #[cfg(CONFIG_CPUMASK_OFFSTACK)] 325 + // SAFETY: By the type invariant, `self.as_raw` is a valid argument to `free_cpumask_var`. 326 + unsafe { 327 + bindings::free_cpumask_var(self.as_raw()) 328 + }; 329 + } 330 + }
+7
rust/kernel/lib.rs
··· 44 44 pub mod block; 45 45 #[doc(hidden)] 46 46 pub mod build_assert; 47 + pub mod clk; 47 48 #[cfg(CONFIG_CONFIGFS_FS)] 48 49 pub mod configfs; 50 + pub mod cpu; 51 + #[cfg(CONFIG_CPU_FREQ)] 52 + pub mod cpufreq; 53 + pub mod cpumask; 49 54 pub mod cred; 50 55 pub mod device; 51 56 pub mod device_id; ··· 75 70 #[cfg(CONFIG_NET)] 76 71 pub mod net; 77 72 pub mod of; 73 + #[cfg(CONFIG_PM_OPP)] 74 + pub mod opp; 78 75 pub mod page; 79 76 #[cfg(CONFIG_PCI)] 80 77 pub mod pci;
+1146
rust/kernel/opp.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + //! Operating performance points. 4 + //! 5 + //! This module provides rust abstractions for interacting with the OPP subsystem. 6 + //! 7 + //! C header: [`include/linux/pm_opp.h`](srctree/include/linux/pm_opp.h) 8 + //! 9 + //! Reference: <https://docs.kernel.org/power/opp.html> 10 + 11 + use crate::{ 12 + clk::Hertz, 13 + cpumask::{Cpumask, CpumaskVar}, 14 + device::Device, 15 + error::{code::*, from_err_ptr, from_result, to_result, Error, Result, VTABLE_DEFAULT_ERROR}, 16 + ffi::c_ulong, 17 + prelude::*, 18 + str::CString, 19 + types::{ARef, AlwaysRefCounted, Opaque}, 20 + }; 21 + 22 + #[cfg(CONFIG_CPU_FREQ)] 23 + /// Frequency table implementation. 24 + mod freq { 25 + use super::*; 26 + use crate::cpufreq; 27 + use core::ops::Deref; 28 + 29 + /// OPP frequency table. 30 + /// 31 + /// A [`cpufreq::Table`] created from [`Table`]. 32 + pub struct FreqTable { 33 + dev: ARef<Device>, 34 + ptr: *mut bindings::cpufreq_frequency_table, 35 + } 36 + 37 + impl FreqTable { 38 + /// Creates a new instance of [`FreqTable`] from [`Table`]. 39 + pub(crate) fn new(table: &Table) -> Result<Self> { 40 + let mut ptr: *mut bindings::cpufreq_frequency_table = ptr::null_mut(); 41 + 42 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 43 + // requirements. 44 + to_result(unsafe { 45 + bindings::dev_pm_opp_init_cpufreq_table(table.dev.as_raw(), &mut ptr) 46 + })?; 47 + 48 + Ok(Self { 49 + dev: table.dev.clone(), 50 + ptr, 51 + }) 52 + } 53 + 54 + /// Returns a reference to the underlying [`cpufreq::Table`]. 55 + #[inline] 56 + fn table(&self) -> &cpufreq::Table { 57 + // SAFETY: The `ptr` is guaranteed by the C code to be valid. 58 + unsafe { cpufreq::Table::from_raw(self.ptr) } 59 + } 60 + } 61 + 62 + impl Deref for FreqTable { 63 + type Target = cpufreq::Table; 64 + 65 + #[inline] 66 + fn deref(&self) -> &Self::Target { 67 + self.table() 68 + } 69 + } 70 + 71 + impl Drop for FreqTable { 72 + fn drop(&mut self) { 73 + // SAFETY: The pointer was created via `dev_pm_opp_init_cpufreq_table`, and is only 74 + // freed here. 75 + unsafe { 76 + bindings::dev_pm_opp_free_cpufreq_table(self.dev.as_raw(), &mut self.as_raw()) 77 + }; 78 + } 79 + } 80 + } 81 + 82 + #[cfg(CONFIG_CPU_FREQ)] 83 + pub use freq::FreqTable; 84 + 85 + use core::{marker::PhantomData, ptr}; 86 + 87 + use macros::vtable; 88 + 89 + /// Creates a null-terminated slice of pointers to [`Cstring`]s. 90 + fn to_c_str_array(names: &[CString]) -> Result<KVec<*const u8>> { 91 + // Allocated a null-terminated vector of pointers. 92 + let mut list = KVec::with_capacity(names.len() + 1, GFP_KERNEL)?; 93 + 94 + for name in names.iter() { 95 + list.push(name.as_ptr() as _, GFP_KERNEL)?; 96 + } 97 + 98 + list.push(ptr::null(), GFP_KERNEL)?; 99 + Ok(list) 100 + } 101 + 102 + /// The voltage unit. 103 + /// 104 + /// Represents voltage in microvolts, wrapping a [`c_ulong`] value. 105 + /// 106 + /// ## Examples 107 + /// 108 + /// ``` 109 + /// use kernel::opp::MicroVolt; 110 + /// 111 + /// let raw = 90500; 112 + /// let volt = MicroVolt(raw); 113 + /// 114 + /// assert_eq!(usize::from(volt), raw); 115 + /// assert_eq!(volt, MicroVolt(raw)); 116 + /// ``` 117 + #[derive(Copy, Clone, PartialEq, Eq, Debug)] 118 + pub struct MicroVolt(pub c_ulong); 119 + 120 + impl From<MicroVolt> for c_ulong { 121 + #[inline] 122 + fn from(volt: MicroVolt) -> Self { 123 + volt.0 124 + } 125 + } 126 + 127 + /// The power unit. 128 + /// 129 + /// Represents power in microwatts, wrapping a [`c_ulong`] value. 130 + /// 131 + /// ## Examples 132 + /// 133 + /// ``` 134 + /// use kernel::opp::MicroWatt; 135 + /// 136 + /// let raw = 1000000; 137 + /// let power = MicroWatt(raw); 138 + /// 139 + /// assert_eq!(usize::from(power), raw); 140 + /// assert_eq!(power, MicroWatt(raw)); 141 + /// ``` 142 + #[derive(Copy, Clone, PartialEq, Eq, Debug)] 143 + pub struct MicroWatt(pub c_ulong); 144 + 145 + impl From<MicroWatt> for c_ulong { 146 + #[inline] 147 + fn from(power: MicroWatt) -> Self { 148 + power.0 149 + } 150 + } 151 + 152 + /// Handle for a dynamically created [`OPP`]. 153 + /// 154 + /// The associated [`OPP`] is automatically removed when the [`Token`] is dropped. 155 + /// 156 + /// ## Examples 157 + /// 158 + /// The following example demonstrates how to create an [`OPP`] dynamically. 159 + /// 160 + /// ``` 161 + /// use kernel::clk::Hertz; 162 + /// use kernel::device::Device; 163 + /// use kernel::error::Result; 164 + /// use kernel::opp::{Data, MicroVolt, Token}; 165 + /// use kernel::types::ARef; 166 + /// 167 + /// fn create_opp(dev: &ARef<Device>, freq: Hertz, volt: MicroVolt, level: u32) -> Result<Token> { 168 + /// let data = Data::new(freq, volt, level, false); 169 + /// 170 + /// // OPP is removed once token goes out of scope. 171 + /// data.add_opp(dev) 172 + /// } 173 + /// ``` 174 + pub struct Token { 175 + dev: ARef<Device>, 176 + freq: Hertz, 177 + } 178 + 179 + impl Token { 180 + /// Dynamically adds an [`OPP`] and returns a [`Token`] that removes it on drop. 181 + fn new(dev: &ARef<Device>, mut data: Data) -> Result<Self> { 182 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 183 + // requirements. 184 + to_result(unsafe { bindings::dev_pm_opp_add_dynamic(dev.as_raw(), &mut data.0) })?; 185 + Ok(Self { 186 + dev: dev.clone(), 187 + freq: data.freq(), 188 + }) 189 + } 190 + } 191 + 192 + impl Drop for Token { 193 + fn drop(&mut self) { 194 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 195 + // requirements. 196 + unsafe { bindings::dev_pm_opp_remove(self.dev.as_raw(), self.freq.into()) }; 197 + } 198 + } 199 + 200 + /// OPP data. 201 + /// 202 + /// Rust abstraction for the C `struct dev_pm_opp_data`, used to define operating performance 203 + /// points (OPPs) dynamically. 204 + /// 205 + /// ## Examples 206 + /// 207 + /// The following example demonstrates how to create an [`OPP`] with [`Data`]. 208 + /// 209 + /// ``` 210 + /// use kernel::clk::Hertz; 211 + /// use kernel::device::Device; 212 + /// use kernel::error::Result; 213 + /// use kernel::opp::{Data, MicroVolt, Token}; 214 + /// use kernel::types::ARef; 215 + /// 216 + /// fn create_opp(dev: &ARef<Device>, freq: Hertz, volt: MicroVolt, level: u32) -> Result<Token> { 217 + /// let data = Data::new(freq, volt, level, false); 218 + /// 219 + /// // OPP is removed once token goes out of scope. 220 + /// data.add_opp(dev) 221 + /// } 222 + /// ``` 223 + #[repr(transparent)] 224 + pub struct Data(bindings::dev_pm_opp_data); 225 + 226 + impl Data { 227 + /// Creates a new instance of [`Data`]. 228 + /// 229 + /// This can be used to define a dynamic OPP to be added to a device. 230 + pub fn new(freq: Hertz, volt: MicroVolt, level: u32, turbo: bool) -> Self { 231 + Self(bindings::dev_pm_opp_data { 232 + turbo, 233 + freq: freq.into(), 234 + u_volt: volt.into(), 235 + level, 236 + }) 237 + } 238 + 239 + /// Adds an [`OPP`] dynamically. 240 + /// 241 + /// Returns a [`Token`] that ensures the OPP is automatically removed 242 + /// when it goes out of scope. 243 + #[inline] 244 + pub fn add_opp(self, dev: &ARef<Device>) -> Result<Token> { 245 + Token::new(dev, self) 246 + } 247 + 248 + /// Returns the frequency associated with this OPP data. 249 + #[inline] 250 + fn freq(&self) -> Hertz { 251 + Hertz(self.0.freq) 252 + } 253 + } 254 + 255 + /// [`OPP`] search options. 256 + /// 257 + /// ## Examples 258 + /// 259 + /// Defines how to search for an [`OPP`] in a [`Table`] relative to a frequency. 260 + /// 261 + /// ``` 262 + /// use kernel::clk::Hertz; 263 + /// use kernel::error::Result; 264 + /// use kernel::opp::{OPP, SearchType, Table}; 265 + /// use kernel::types::ARef; 266 + /// 267 + /// fn find_opp(table: &Table, freq: Hertz) -> Result<ARef<OPP>> { 268 + /// let opp = table.opp_from_freq(freq, Some(true), None, SearchType::Exact)?; 269 + /// 270 + /// pr_info!("OPP frequency is: {:?}\n", opp.freq(None)); 271 + /// pr_info!("OPP voltage is: {:?}\n", opp.voltage()); 272 + /// pr_info!("OPP level is: {}\n", opp.level()); 273 + /// pr_info!("OPP power is: {:?}\n", opp.power()); 274 + /// 275 + /// Ok(opp) 276 + /// } 277 + /// ``` 278 + #[derive(Copy, Clone, Debug, Eq, PartialEq)] 279 + pub enum SearchType { 280 + /// Match the exact frequency. 281 + Exact, 282 + /// Find the highest frequency less than or equal to the given value. 283 + Floor, 284 + /// Find the lowest frequency greater than or equal to the given value. 285 + Ceil, 286 + } 287 + 288 + /// OPP configuration callbacks. 289 + /// 290 + /// Implement this trait to customize OPP clock and regulator setup for your device. 291 + #[vtable] 292 + pub trait ConfigOps { 293 + /// This is typically used to scale clocks when transitioning between OPPs. 294 + #[inline] 295 + fn config_clks(_dev: &Device, _table: &Table, _opp: &OPP, _scaling_down: bool) -> Result { 296 + build_error!(VTABLE_DEFAULT_ERROR) 297 + } 298 + 299 + /// This provides access to the old and new OPPs, allowing for safe regulator adjustments. 300 + #[inline] 301 + fn config_regulators( 302 + _dev: &Device, 303 + _opp_old: &OPP, 304 + _opp_new: &OPP, 305 + _data: *mut *mut bindings::regulator, 306 + _count: u32, 307 + ) -> Result { 308 + build_error!(VTABLE_DEFAULT_ERROR) 309 + } 310 + } 311 + 312 + /// OPP configuration token. 313 + /// 314 + /// Returned by the OPP core when configuration is applied to a [`Device`]. The associated 315 + /// configuration is automatically cleared when the token is dropped. 316 + pub struct ConfigToken(i32); 317 + 318 + impl Drop for ConfigToken { 319 + fn drop(&mut self) { 320 + // SAFETY: This is the same token value returned by the C code via `dev_pm_opp_set_config`. 321 + unsafe { bindings::dev_pm_opp_clear_config(self.0) }; 322 + } 323 + } 324 + 325 + /// OPP configurations. 326 + /// 327 + /// Rust abstraction for the C `struct dev_pm_opp_config`. 328 + /// 329 + /// ## Examples 330 + /// 331 + /// The following example demonstrates how to set OPP property-name configuration for a [`Device`]. 332 + /// 333 + /// ``` 334 + /// use kernel::device::Device; 335 + /// use kernel::error::Result; 336 + /// use kernel::opp::{Config, ConfigOps, ConfigToken}; 337 + /// use kernel::str::CString; 338 + /// use kernel::types::ARef; 339 + /// use kernel::macros::vtable; 340 + /// 341 + /// #[derive(Default)] 342 + /// struct Driver; 343 + /// 344 + /// #[vtable] 345 + /// impl ConfigOps for Driver {} 346 + /// 347 + /// fn configure(dev: &ARef<Device>) -> Result<ConfigToken> { 348 + /// let name = CString::try_from_fmt(fmt!("{}", "slow"))?; 349 + /// 350 + /// // The OPP configuration is cleared once the [`ConfigToken`] goes out of scope. 351 + /// Config::<Driver>::new() 352 + /// .set_prop_name(name)? 353 + /// .set(dev) 354 + /// } 355 + /// ``` 356 + #[derive(Default)] 357 + pub struct Config<T: ConfigOps> 358 + where 359 + T: Default, 360 + { 361 + clk_names: Option<KVec<CString>>, 362 + prop_name: Option<CString>, 363 + regulator_names: Option<KVec<CString>>, 364 + supported_hw: Option<KVec<u32>>, 365 + 366 + // Tuple containing (required device, index) 367 + required_dev: Option<(ARef<Device>, u32)>, 368 + _data: PhantomData<T>, 369 + } 370 + 371 + impl<T: ConfigOps + Default> Config<T> { 372 + /// Creates a new instance of [`Config`]. 373 + #[inline] 374 + pub fn new() -> Self { 375 + Self::default() 376 + } 377 + 378 + /// Initializes clock names. 379 + pub fn set_clk_names(mut self, names: KVec<CString>) -> Result<Self> { 380 + if self.clk_names.is_some() { 381 + return Err(EBUSY); 382 + } 383 + 384 + if names.is_empty() { 385 + return Err(EINVAL); 386 + } 387 + 388 + self.clk_names = Some(names); 389 + Ok(self) 390 + } 391 + 392 + /// Initializes property name. 393 + pub fn set_prop_name(mut self, name: CString) -> Result<Self> { 394 + if self.prop_name.is_some() { 395 + return Err(EBUSY); 396 + } 397 + 398 + self.prop_name = Some(name); 399 + Ok(self) 400 + } 401 + 402 + /// Initializes regulator names. 403 + pub fn set_regulator_names(mut self, names: KVec<CString>) -> Result<Self> { 404 + if self.regulator_names.is_some() { 405 + return Err(EBUSY); 406 + } 407 + 408 + if names.is_empty() { 409 + return Err(EINVAL); 410 + } 411 + 412 + self.regulator_names = Some(names); 413 + 414 + Ok(self) 415 + } 416 + 417 + /// Initializes required devices. 418 + pub fn set_required_dev(mut self, dev: ARef<Device>, index: u32) -> Result<Self> { 419 + if self.required_dev.is_some() { 420 + return Err(EBUSY); 421 + } 422 + 423 + self.required_dev = Some((dev, index)); 424 + Ok(self) 425 + } 426 + 427 + /// Initializes supported hardware. 428 + pub fn set_supported_hw(mut self, hw: KVec<u32>) -> Result<Self> { 429 + if self.supported_hw.is_some() { 430 + return Err(EBUSY); 431 + } 432 + 433 + if hw.is_empty() { 434 + return Err(EINVAL); 435 + } 436 + 437 + self.supported_hw = Some(hw); 438 + Ok(self) 439 + } 440 + 441 + /// Sets the configuration with the OPP core. 442 + /// 443 + /// The returned [`ConfigToken`] will remove the configuration when dropped. 444 + pub fn set(self, dev: &Device) -> Result<ConfigToken> { 445 + let (_clk_list, clk_names) = match &self.clk_names { 446 + Some(x) => { 447 + let list = to_c_str_array(x)?; 448 + let ptr = list.as_ptr(); 449 + (Some(list), ptr) 450 + } 451 + None => (None, ptr::null()), 452 + }; 453 + 454 + let (_regulator_list, regulator_names) = match &self.regulator_names { 455 + Some(x) => { 456 + let list = to_c_str_array(x)?; 457 + let ptr = list.as_ptr(); 458 + (Some(list), ptr) 459 + } 460 + None => (None, ptr::null()), 461 + }; 462 + 463 + let prop_name = self 464 + .prop_name 465 + .as_ref() 466 + .map_or(ptr::null(), |p| p.as_char_ptr()); 467 + 468 + let (supported_hw, supported_hw_count) = self 469 + .supported_hw 470 + .as_ref() 471 + .map_or((ptr::null(), 0), |hw| (hw.as_ptr(), hw.len() as u32)); 472 + 473 + let (required_dev, required_dev_index) = self 474 + .required_dev 475 + .as_ref() 476 + .map_or((ptr::null_mut(), 0), |(dev, idx)| (dev.as_raw(), *idx)); 477 + 478 + let mut config = bindings::dev_pm_opp_config { 479 + clk_names, 480 + config_clks: if T::HAS_CONFIG_CLKS { 481 + Some(Self::config_clks) 482 + } else { 483 + None 484 + }, 485 + prop_name, 486 + regulator_names, 487 + config_regulators: if T::HAS_CONFIG_REGULATORS { 488 + Some(Self::config_regulators) 489 + } else { 490 + None 491 + }, 492 + supported_hw, 493 + supported_hw_count, 494 + 495 + required_dev, 496 + required_dev_index, 497 + }; 498 + 499 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 500 + // requirements. The OPP core guarantees not to access fields of [`Config`] after this call 501 + // and so we don't need to save a copy of them for future use. 502 + let ret = unsafe { bindings::dev_pm_opp_set_config(dev.as_raw(), &mut config) }; 503 + if ret < 0 { 504 + Err(Error::from_errno(ret)) 505 + } else { 506 + Ok(ConfigToken(ret)) 507 + } 508 + } 509 + 510 + /// Config's clk callback. 511 + /// 512 + /// SAFETY: Called from C. Inputs must be valid pointers. 513 + extern "C" fn config_clks( 514 + dev: *mut bindings::device, 515 + opp_table: *mut bindings::opp_table, 516 + opp: *mut bindings::dev_pm_opp, 517 + _data: *mut kernel::ffi::c_void, 518 + scaling_down: bool, 519 + ) -> kernel::ffi::c_int { 520 + from_result(|| { 521 + // SAFETY: 'dev' is guaranteed by the C code to be valid. 522 + let dev = unsafe { Device::get_device(dev) }; 523 + T::config_clks( 524 + &dev, 525 + // SAFETY: 'opp_table' is guaranteed by the C code to be valid. 526 + &unsafe { Table::from_raw_table(opp_table, &dev) }, 527 + // SAFETY: 'opp' is guaranteed by the C code to be valid. 528 + unsafe { OPP::from_raw_opp(opp)? }, 529 + scaling_down, 530 + ) 531 + .map(|()| 0) 532 + }) 533 + } 534 + 535 + /// Config's regulator callback. 536 + /// 537 + /// SAFETY: Called from C. Inputs must be valid pointers. 538 + extern "C" fn config_regulators( 539 + dev: *mut bindings::device, 540 + old_opp: *mut bindings::dev_pm_opp, 541 + new_opp: *mut bindings::dev_pm_opp, 542 + regulators: *mut *mut bindings::regulator, 543 + count: kernel::ffi::c_uint, 544 + ) -> kernel::ffi::c_int { 545 + from_result(|| { 546 + // SAFETY: 'dev' is guaranteed by the C code to be valid. 547 + let dev = unsafe { Device::get_device(dev) }; 548 + T::config_regulators( 549 + &dev, 550 + // SAFETY: 'old_opp' is guaranteed by the C code to be valid. 551 + unsafe { OPP::from_raw_opp(old_opp)? }, 552 + // SAFETY: 'new_opp' is guaranteed by the C code to be valid. 553 + unsafe { OPP::from_raw_opp(new_opp)? }, 554 + regulators, 555 + count, 556 + ) 557 + .map(|()| 0) 558 + }) 559 + } 560 + } 561 + 562 + /// A reference-counted OPP table. 563 + /// 564 + /// Rust abstraction for the C `struct opp_table`. 565 + /// 566 + /// # Invariants 567 + /// 568 + /// The pointer stored in `Self` is non-null and valid for the lifetime of the [`Table`]. 569 + /// 570 + /// Instances of this type are reference-counted. 571 + /// 572 + /// ## Examples 573 + /// 574 + /// The following example demonstrates how to get OPP [`Table`] for a [`Cpumask`] and set its 575 + /// frequency. 576 + /// 577 + /// ``` 578 + /// # #![cfg(CONFIG_OF)] 579 + /// use kernel::clk::Hertz; 580 + /// use kernel::cpumask::Cpumask; 581 + /// use kernel::device::Device; 582 + /// use kernel::error::Result; 583 + /// use kernel::opp::Table; 584 + /// use kernel::types::ARef; 585 + /// 586 + /// fn get_table(dev: &ARef<Device>, mask: &mut Cpumask, freq: Hertz) -> Result<Table> { 587 + /// let mut opp_table = Table::from_of_cpumask(dev, mask)?; 588 + /// 589 + /// if opp_table.opp_count()? == 0 { 590 + /// return Err(EINVAL); 591 + /// } 592 + /// 593 + /// pr_info!("Max transition latency is: {} ns\n", opp_table.max_transition_latency_ns()); 594 + /// pr_info!("Suspend frequency is: {:?}\n", opp_table.suspend_freq()); 595 + /// 596 + /// opp_table.set_rate(freq)?; 597 + /// Ok(opp_table) 598 + /// } 599 + /// ``` 600 + pub struct Table { 601 + ptr: *mut bindings::opp_table, 602 + dev: ARef<Device>, 603 + #[allow(dead_code)] 604 + em: bool, 605 + #[allow(dead_code)] 606 + of: bool, 607 + cpus: Option<CpumaskVar>, 608 + } 609 + 610 + /// SAFETY: It is okay to send ownership of [`Table`] across thread boundaries. 611 + unsafe impl Send for Table {} 612 + 613 + /// SAFETY: It is okay to access [`Table`] through shared references from other threads because 614 + /// we're either accessing properties that don't change or that are properly synchronised by C code. 615 + unsafe impl Sync for Table {} 616 + 617 + impl Table { 618 + /// Creates a new reference-counted [`Table`] from a raw pointer. 619 + /// 620 + /// # Safety 621 + /// 622 + /// Callers must ensure that `ptr` is valid and non-null. 623 + unsafe fn from_raw_table(ptr: *mut bindings::opp_table, dev: &ARef<Device>) -> Self { 624 + // SAFETY: By the safety requirements, ptr is valid and its refcount will be incremented. 625 + // 626 + // INVARIANT: The reference-count is decremented when [`Table`] goes out of scope. 627 + unsafe { bindings::dev_pm_opp_get_opp_table_ref(ptr) }; 628 + 629 + Self { 630 + ptr, 631 + dev: dev.clone(), 632 + em: false, 633 + of: false, 634 + cpus: None, 635 + } 636 + } 637 + 638 + /// Creates a new reference-counted [`Table`] instance for a [`Device`]. 639 + pub fn from_dev(dev: &Device) -> Result<Self> { 640 + // SAFETY: The requirements are satisfied by the existence of the [`Device`] and its safety 641 + // requirements. 642 + // 643 + // INVARIANT: The reference-count is incremented by the C code and is decremented when 644 + // [`Table`] goes out of scope. 645 + let ptr = from_err_ptr(unsafe { bindings::dev_pm_opp_get_opp_table(dev.as_raw()) })?; 646 + 647 + Ok(Self { 648 + ptr, 649 + dev: dev.into(), 650 + em: false, 651 + of: false, 652 + cpus: None, 653 + }) 654 + } 655 + 656 + /// Creates a new reference-counted [`Table`] instance for a [`Device`] based on device tree 657 + /// entries. 658 + #[cfg(CONFIG_OF)] 659 + pub fn from_of(dev: &ARef<Device>, index: i32) -> Result<Self> { 660 + // SAFETY: The requirements are satisfied by the existence of the [`Device`] and its safety 661 + // requirements. 662 + // 663 + // INVARIANT: The reference-count is incremented by the C code and is decremented when 664 + // [`Table`] goes out of scope. 665 + to_result(unsafe { bindings::dev_pm_opp_of_add_table_indexed(dev.as_raw(), index) })?; 666 + 667 + // Get the newly created [`Table`]. 668 + let mut table = Self::from_dev(dev)?; 669 + table.of = true; 670 + 671 + Ok(table) 672 + } 673 + 674 + /// Remove device tree based [`Table`]. 675 + #[cfg(CONFIG_OF)] 676 + #[inline] 677 + fn remove_of(&self) { 678 + // SAFETY: The requirements are satisfied by the existence of the [`Device`] and its safety 679 + // requirements. We took the reference from [`from_of`] earlier, it is safe to drop the 680 + // same now. 681 + unsafe { bindings::dev_pm_opp_of_remove_table(self.dev.as_raw()) }; 682 + } 683 + 684 + /// Creates a new reference-counted [`Table`] instance for a [`Cpumask`] based on device tree 685 + /// entries. 686 + #[cfg(CONFIG_OF)] 687 + pub fn from_of_cpumask(dev: &Device, cpumask: &mut Cpumask) -> Result<Self> { 688 + // SAFETY: The cpumask is valid and the returned pointer will be owned by the [`Table`] 689 + // instance. 690 + // 691 + // INVARIANT: The reference-count is incremented by the C code and is decremented when 692 + // [`Table`] goes out of scope. 693 + to_result(unsafe { bindings::dev_pm_opp_of_cpumask_add_table(cpumask.as_raw()) })?; 694 + 695 + // Fetch the newly created table. 696 + let mut table = Self::from_dev(dev)?; 697 + table.cpus = Some(CpumaskVar::try_clone(cpumask)?); 698 + 699 + Ok(table) 700 + } 701 + 702 + /// Remove device tree based [`Table`] for a [`Cpumask`]. 703 + #[cfg(CONFIG_OF)] 704 + #[inline] 705 + fn remove_of_cpumask(&self, cpumask: &Cpumask) { 706 + // SAFETY: The cpumask is valid and we took the reference from [`from_of_cpumask`] earlier, 707 + // it is safe to drop the same now. 708 + unsafe { bindings::dev_pm_opp_of_cpumask_remove_table(cpumask.as_raw()) }; 709 + } 710 + 711 + /// Returns the number of [`OPP`]s in the [`Table`]. 712 + pub fn opp_count(&self) -> Result<u32> { 713 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 714 + // requirements. 715 + let ret = unsafe { bindings::dev_pm_opp_get_opp_count(self.dev.as_raw()) }; 716 + if ret < 0 { 717 + Err(Error::from_errno(ret)) 718 + } else { 719 + Ok(ret as u32) 720 + } 721 + } 722 + 723 + /// Returns max clock latency (in nanoseconds) of the [`OPP`]s in the [`Table`]. 724 + #[inline] 725 + pub fn max_clock_latency_ns(&self) -> usize { 726 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 727 + // requirements. 728 + unsafe { bindings::dev_pm_opp_get_max_clock_latency(self.dev.as_raw()) } 729 + } 730 + 731 + /// Returns max volt latency (in nanoseconds) of the [`OPP`]s in the [`Table`]. 732 + #[inline] 733 + pub fn max_volt_latency_ns(&self) -> usize { 734 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 735 + // requirements. 736 + unsafe { bindings::dev_pm_opp_get_max_volt_latency(self.dev.as_raw()) } 737 + } 738 + 739 + /// Returns max transition latency (in nanoseconds) of the [`OPP`]s in the [`Table`]. 740 + #[inline] 741 + pub fn max_transition_latency_ns(&self) -> usize { 742 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 743 + // requirements. 744 + unsafe { bindings::dev_pm_opp_get_max_transition_latency(self.dev.as_raw()) } 745 + } 746 + 747 + /// Returns the suspend [`OPP`]'s frequency. 748 + #[inline] 749 + pub fn suspend_freq(&self) -> Hertz { 750 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 751 + // requirements. 752 + Hertz(unsafe { bindings::dev_pm_opp_get_suspend_opp_freq(self.dev.as_raw()) }) 753 + } 754 + 755 + /// Synchronizes regulators used by the [`Table`]. 756 + #[inline] 757 + pub fn sync_regulators(&self) -> Result { 758 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 759 + // requirements. 760 + to_result(unsafe { bindings::dev_pm_opp_sync_regulators(self.dev.as_raw()) }) 761 + } 762 + 763 + /// Gets sharing CPUs. 764 + #[inline] 765 + pub fn sharing_cpus(dev: &Device, cpumask: &mut Cpumask) -> Result { 766 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 767 + // requirements. 768 + to_result(unsafe { bindings::dev_pm_opp_get_sharing_cpus(dev.as_raw(), cpumask.as_raw()) }) 769 + } 770 + 771 + /// Sets sharing CPUs. 772 + pub fn set_sharing_cpus(&mut self, cpumask: &mut Cpumask) -> Result { 773 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 774 + // requirements. 775 + to_result(unsafe { 776 + bindings::dev_pm_opp_set_sharing_cpus(self.dev.as_raw(), cpumask.as_raw()) 777 + })?; 778 + 779 + if let Some(mask) = self.cpus.as_mut() { 780 + // Update the cpumask as this will be used while removing the table. 781 + cpumask.copy(mask); 782 + } 783 + 784 + Ok(()) 785 + } 786 + 787 + /// Gets sharing CPUs from device tree. 788 + #[cfg(CONFIG_OF)] 789 + #[inline] 790 + pub fn of_sharing_cpus(dev: &Device, cpumask: &mut Cpumask) -> Result { 791 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 792 + // requirements. 793 + to_result(unsafe { 794 + bindings::dev_pm_opp_of_get_sharing_cpus(dev.as_raw(), cpumask.as_raw()) 795 + }) 796 + } 797 + 798 + /// Updates the voltage value for an [`OPP`]. 799 + #[inline] 800 + pub fn adjust_voltage( 801 + &self, 802 + freq: Hertz, 803 + volt: MicroVolt, 804 + volt_min: MicroVolt, 805 + volt_max: MicroVolt, 806 + ) -> Result { 807 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 808 + // requirements. 809 + to_result(unsafe { 810 + bindings::dev_pm_opp_adjust_voltage( 811 + self.dev.as_raw(), 812 + freq.into(), 813 + volt.into(), 814 + volt_min.into(), 815 + volt_max.into(), 816 + ) 817 + }) 818 + } 819 + 820 + /// Creates [`FreqTable`] from [`Table`]. 821 + #[cfg(CONFIG_CPU_FREQ)] 822 + #[inline] 823 + pub fn cpufreq_table(&mut self) -> Result<FreqTable> { 824 + FreqTable::new(self) 825 + } 826 + 827 + /// Configures device with [`OPP`] matching the frequency value. 828 + #[inline] 829 + pub fn set_rate(&self, freq: Hertz) -> Result { 830 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 831 + // requirements. 832 + to_result(unsafe { bindings::dev_pm_opp_set_rate(self.dev.as_raw(), freq.into()) }) 833 + } 834 + 835 + /// Configures device with [`OPP`]. 836 + #[inline] 837 + pub fn set_opp(&self, opp: &OPP) -> Result { 838 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 839 + // requirements. 840 + to_result(unsafe { bindings::dev_pm_opp_set_opp(self.dev.as_raw(), opp.as_raw()) }) 841 + } 842 + 843 + /// Finds [`OPP`] based on frequency. 844 + pub fn opp_from_freq( 845 + &self, 846 + freq: Hertz, 847 + available: Option<bool>, 848 + index: Option<u32>, 849 + stype: SearchType, 850 + ) -> Result<ARef<OPP>> { 851 + let raw_dev = self.dev.as_raw(); 852 + let index = index.unwrap_or(0); 853 + let mut rate = freq.into(); 854 + 855 + let ptr = from_err_ptr(match stype { 856 + SearchType::Exact => { 857 + if let Some(available) = available { 858 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and 859 + // its safety requirements. The returned pointer will be owned by the new 860 + // [`OPP`] instance. 861 + unsafe { 862 + bindings::dev_pm_opp_find_freq_exact_indexed( 863 + raw_dev, rate, index, available, 864 + ) 865 + } 866 + } else { 867 + return Err(EINVAL); 868 + } 869 + } 870 + 871 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 872 + // requirements. The returned pointer will be owned by the new [`OPP`] instance. 873 + SearchType::Ceil => unsafe { 874 + bindings::dev_pm_opp_find_freq_ceil_indexed(raw_dev, &mut rate, index) 875 + }, 876 + 877 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 878 + // requirements. The returned pointer will be owned by the new [`OPP`] instance. 879 + SearchType::Floor => unsafe { 880 + bindings::dev_pm_opp_find_freq_floor_indexed(raw_dev, &mut rate, index) 881 + }, 882 + })?; 883 + 884 + // SAFETY: The `ptr` is guaranteed by the C code to be valid. 885 + unsafe { OPP::from_raw_opp_owned(ptr) } 886 + } 887 + 888 + /// Finds [`OPP`] based on level. 889 + pub fn opp_from_level(&self, mut level: u32, stype: SearchType) -> Result<ARef<OPP>> { 890 + let raw_dev = self.dev.as_raw(); 891 + 892 + let ptr = from_err_ptr(match stype { 893 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 894 + // requirements. The returned pointer will be owned by the new [`OPP`] instance. 895 + SearchType::Exact => unsafe { bindings::dev_pm_opp_find_level_exact(raw_dev, level) }, 896 + 897 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 898 + // requirements. The returned pointer will be owned by the new [`OPP`] instance. 899 + SearchType::Ceil => unsafe { 900 + bindings::dev_pm_opp_find_level_ceil(raw_dev, &mut level) 901 + }, 902 + 903 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 904 + // requirements. The returned pointer will be owned by the new [`OPP`] instance. 905 + SearchType::Floor => unsafe { 906 + bindings::dev_pm_opp_find_level_floor(raw_dev, &mut level) 907 + }, 908 + })?; 909 + 910 + // SAFETY: The `ptr` is guaranteed by the C code to be valid. 911 + unsafe { OPP::from_raw_opp_owned(ptr) } 912 + } 913 + 914 + /// Finds [`OPP`] based on bandwidth. 915 + pub fn opp_from_bw(&self, mut bw: u32, index: i32, stype: SearchType) -> Result<ARef<OPP>> { 916 + let raw_dev = self.dev.as_raw(); 917 + 918 + let ptr = from_err_ptr(match stype { 919 + // The OPP core doesn't support this yet. 920 + SearchType::Exact => return Err(EINVAL), 921 + 922 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 923 + // requirements. The returned pointer will be owned by the new [`OPP`] instance. 924 + SearchType::Ceil => unsafe { 925 + bindings::dev_pm_opp_find_bw_ceil(raw_dev, &mut bw, index) 926 + }, 927 + 928 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 929 + // requirements. The returned pointer will be owned by the new [`OPP`] instance. 930 + SearchType::Floor => unsafe { 931 + bindings::dev_pm_opp_find_bw_floor(raw_dev, &mut bw, index) 932 + }, 933 + })?; 934 + 935 + // SAFETY: The `ptr` is guaranteed by the C code to be valid. 936 + unsafe { OPP::from_raw_opp_owned(ptr) } 937 + } 938 + 939 + /// Enables the [`OPP`]. 940 + #[inline] 941 + pub fn enable_opp(&self, freq: Hertz) -> Result { 942 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 943 + // requirements. 944 + to_result(unsafe { bindings::dev_pm_opp_enable(self.dev.as_raw(), freq.into()) }) 945 + } 946 + 947 + /// Disables the [`OPP`]. 948 + #[inline] 949 + pub fn disable_opp(&self, freq: Hertz) -> Result { 950 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 951 + // requirements. 952 + to_result(unsafe { bindings::dev_pm_opp_disable(self.dev.as_raw(), freq.into()) }) 953 + } 954 + 955 + /// Registers with the Energy model. 956 + #[cfg(CONFIG_OF)] 957 + pub fn of_register_em(&mut self, cpumask: &mut Cpumask) -> Result { 958 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 959 + // requirements. 960 + to_result(unsafe { 961 + bindings::dev_pm_opp_of_register_em(self.dev.as_raw(), cpumask.as_raw()) 962 + })?; 963 + 964 + self.em = true; 965 + Ok(()) 966 + } 967 + 968 + /// Unregisters with the Energy model. 969 + #[cfg(all(CONFIG_OF, CONFIG_ENERGY_MODEL))] 970 + #[inline] 971 + fn of_unregister_em(&self) { 972 + // SAFETY: The requirements are satisfied by the existence of [`Device`] and its safety 973 + // requirements. We registered with the EM framework earlier, it is safe to unregister now. 974 + unsafe { bindings::em_dev_unregister_perf_domain(self.dev.as_raw()) }; 975 + } 976 + } 977 + 978 + impl Drop for Table { 979 + fn drop(&mut self) { 980 + // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe 981 + // to relinquish it now. 982 + unsafe { bindings::dev_pm_opp_put_opp_table(self.ptr) }; 983 + 984 + #[cfg(CONFIG_OF)] 985 + { 986 + #[cfg(CONFIG_ENERGY_MODEL)] 987 + if self.em { 988 + self.of_unregister_em(); 989 + } 990 + 991 + if self.of { 992 + self.remove_of(); 993 + } else if let Some(cpumask) = self.cpus.take() { 994 + self.remove_of_cpumask(&cpumask); 995 + } 996 + } 997 + } 998 + } 999 + 1000 + /// A reference-counted Operating performance point (OPP). 1001 + /// 1002 + /// Rust abstraction for the C `struct dev_pm_opp`. 1003 + /// 1004 + /// # Invariants 1005 + /// 1006 + /// The pointer stored in `Self` is non-null and valid for the lifetime of the [`OPP`]. 1007 + /// 1008 + /// Instances of this type are reference-counted. The reference count is incremented by the 1009 + /// `dev_pm_opp_get` function and decremented by `dev_pm_opp_put`. The Rust type `ARef<OPP>` 1010 + /// represents a pointer that owns a reference count on the [`OPP`]. 1011 + /// 1012 + /// A reference to the [`OPP`], &[`OPP`], isn't refcounted by the Rust code. 1013 + /// 1014 + /// ## Examples 1015 + /// 1016 + /// The following example demonstrates how to get [`OPP`] corresponding to a frequency value and 1017 + /// configure the device with it. 1018 + /// 1019 + /// ``` 1020 + /// use kernel::clk::Hertz; 1021 + /// use kernel::error::Result; 1022 + /// use kernel::opp::{SearchType, Table}; 1023 + /// 1024 + /// fn configure_opp(table: &Table, freq: Hertz) -> Result { 1025 + /// let opp = table.opp_from_freq(freq, Some(true), None, SearchType::Exact)?; 1026 + /// 1027 + /// if opp.freq(None) != freq { 1028 + /// return Err(EINVAL); 1029 + /// } 1030 + /// 1031 + /// table.set_opp(&opp) 1032 + /// } 1033 + /// ``` 1034 + #[repr(transparent)] 1035 + pub struct OPP(Opaque<bindings::dev_pm_opp>); 1036 + 1037 + /// SAFETY: It is okay to send the ownership of [`OPP`] across thread boundaries. 1038 + unsafe impl Send for OPP {} 1039 + 1040 + /// SAFETY: It is okay to access [`OPP`] through shared references from other threads because we're 1041 + /// either accessing properties that don't change or that are properly synchronised by C code. 1042 + unsafe impl Sync for OPP {} 1043 + 1044 + /// SAFETY: The type invariants guarantee that [`OPP`] is always refcounted. 1045 + unsafe impl AlwaysRefCounted for OPP { 1046 + fn inc_ref(&self) { 1047 + // SAFETY: The existence of a shared reference means that the refcount is nonzero. 1048 + unsafe { bindings::dev_pm_opp_get(self.0.get()) }; 1049 + } 1050 + 1051 + unsafe fn dec_ref(obj: ptr::NonNull<Self>) { 1052 + // SAFETY: The safety requirements guarantee that the refcount is nonzero. 1053 + unsafe { bindings::dev_pm_opp_put(obj.cast().as_ptr()) } 1054 + } 1055 + } 1056 + 1057 + impl OPP { 1058 + /// Creates an owned reference to a [`OPP`] from a valid pointer. 1059 + /// 1060 + /// The refcount is incremented by the C code and will be decremented by `dec_ref` when the 1061 + /// [`ARef`] object is dropped. 1062 + /// 1063 + /// # Safety 1064 + /// 1065 + /// The caller must ensure that `ptr` is valid and the refcount of the [`OPP`] is incremented. 1066 + /// The caller must also ensure that it doesn't explicitly drop the refcount of the [`OPP`], as 1067 + /// the returned [`ARef`] object takes over the refcount increment on the underlying object and 1068 + /// the same will be dropped along with it. 1069 + pub unsafe fn from_raw_opp_owned(ptr: *mut bindings::dev_pm_opp) -> Result<ARef<Self>> { 1070 + let ptr = ptr::NonNull::new(ptr).ok_or(ENODEV)?; 1071 + 1072 + // SAFETY: The safety requirements guarantee the validity of the pointer. 1073 + // 1074 + // INVARIANT: The reference-count is decremented when [`OPP`] goes out of scope. 1075 + Ok(unsafe { ARef::from_raw(ptr.cast()) }) 1076 + } 1077 + 1078 + /// Creates a reference to a [`OPP`] from a valid pointer. 1079 + /// 1080 + /// The refcount is not updated by the Rust API unless the returned reference is converted to 1081 + /// an [`ARef`] object. 1082 + /// 1083 + /// # Safety 1084 + /// 1085 + /// The caller must ensure that `ptr` is valid and remains valid for the duration of `'a`. 1086 + #[inline] 1087 + pub unsafe fn from_raw_opp<'a>(ptr: *mut bindings::dev_pm_opp) -> Result<&'a Self> { 1088 + // SAFETY: The caller guarantees that the pointer is not dangling and stays valid for the 1089 + // duration of 'a. The cast is okay because [`OPP`] is `repr(transparent)`. 1090 + Ok(unsafe { &*ptr.cast() }) 1091 + } 1092 + 1093 + #[inline] 1094 + fn as_raw(&self) -> *mut bindings::dev_pm_opp { 1095 + self.0.get() 1096 + } 1097 + 1098 + /// Returns the frequency of an [`OPP`]. 1099 + pub fn freq(&self, index: Option<u32>) -> Hertz { 1100 + let index = index.unwrap_or(0); 1101 + 1102 + // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to 1103 + // use it. 1104 + Hertz(unsafe { bindings::dev_pm_opp_get_freq_indexed(self.as_raw(), index) }) 1105 + } 1106 + 1107 + /// Returns the voltage of an [`OPP`]. 1108 + #[inline] 1109 + pub fn voltage(&self) -> MicroVolt { 1110 + // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to 1111 + // use it. 1112 + MicroVolt(unsafe { bindings::dev_pm_opp_get_voltage(self.as_raw()) }) 1113 + } 1114 + 1115 + /// Returns the level of an [`OPP`]. 1116 + #[inline] 1117 + pub fn level(&self) -> u32 { 1118 + // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to 1119 + // use it. 1120 + unsafe { bindings::dev_pm_opp_get_level(self.as_raw()) } 1121 + } 1122 + 1123 + /// Returns the power of an [`OPP`]. 1124 + #[inline] 1125 + pub fn power(&self) -> MicroWatt { 1126 + // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to 1127 + // use it. 1128 + MicroWatt(unsafe { bindings::dev_pm_opp_get_power(self.as_raw()) }) 1129 + } 1130 + 1131 + /// Returns the required pstate of an [`OPP`]. 1132 + #[inline] 1133 + pub fn required_pstate(&self, index: u32) -> u32 { 1134 + // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to 1135 + // use it. 1136 + unsafe { bindings::dev_pm_opp_get_required_pstate(self.as_raw(), index) } 1137 + } 1138 + 1139 + /// Returns true if the [`OPP`] is turbo. 1140 + #[inline] 1141 + pub fn is_turbo(&self) -> bool { 1142 + // SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to 1143 + // use it. 1144 + unsafe { bindings::dev_pm_opp_is_turbo(self.as_raw()) } 1145 + } 1146 + }
+12 -8
rust/macros/module.rs
··· 176 176 177 177 let info = ModuleInfo::parse(&mut it); 178 178 179 - let mut modinfo = ModInfoBuilder::new(info.name.as_ref()); 179 + // Rust does not allow hyphens in identifiers, use underscore instead. 180 + let ident = info.name.replace('-', "_"); 181 + let mut modinfo = ModInfoBuilder::new(ident.as_ref()); 180 182 if let Some(author) = info.author { 181 183 modinfo.emit("author", &author); 182 184 } ··· 303 301 #[doc(hidden)] 304 302 #[link_section = \"{initcall_section}\"] 305 303 #[used] 306 - pub static __{name}_initcall: extern \"C\" fn() -> kernel::ffi::c_int = __{name}_init; 304 + pub static __{ident}_initcall: extern \"C\" fn() -> 305 + kernel::ffi::c_int = __{ident}_init; 307 306 308 307 #[cfg(not(MODULE))] 309 308 #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] 310 309 core::arch::global_asm!( 311 310 r#\".section \"{initcall_section}\", \"a\" 312 - __{name}_initcall: 313 - .long __{name}_init - . 311 + __{ident}_initcall: 312 + .long __{ident}_init - . 314 313 .previous 315 314 \"# 316 315 ); ··· 319 316 #[cfg(not(MODULE))] 320 317 #[doc(hidden)] 321 318 #[no_mangle] 322 - pub extern \"C\" fn __{name}_init() -> kernel::ffi::c_int {{ 319 + pub extern \"C\" fn __{ident}_init() -> kernel::ffi::c_int {{ 323 320 // SAFETY: This function is inaccessible to the outside due to the double 324 321 // module wrapping it. It is called exactly once by the C side via its 325 322 // placement above in the initcall section. ··· 329 326 #[cfg(not(MODULE))] 330 327 #[doc(hidden)] 331 328 #[no_mangle] 332 - pub extern \"C\" fn __{name}_exit() {{ 329 + pub extern \"C\" fn __{ident}_exit() {{ 333 330 // SAFETY: 334 331 // - This function is inaccessible to the outside due to the double 335 332 // module wrapping it. It is called exactly once by the C side via its 336 333 // unique name, 337 - // - furthermore it is only called after `__{name}_init` has returned `0` 338 - // (which delegates to `__init`). 334 + // - furthermore it is only called after `__{ident}_init` has 335 + // returned `0` (which delegates to `__init`). 339 336 unsafe {{ __exit() }} 340 337 }} 341 338 ··· 375 372 ", 376 373 type_ = info.type_, 377 374 name = info.name, 375 + ident = ident, 378 376 modinfo = modinfo.buffer, 379 377 initcall_section = ".initcall6.init" 380 378 )