1
0

Merge branch 'pm-cpufreq'

Merge cpufreq updates for 6.17-rc1:

 - Fix two initialization ordering issues in the cpufreq core and a
   governor initialization error path in it, and clean it up (Lifeng
   Zheng)

 - Add Granite Rapids support in no-HWP mode to the intel_pstate cpufreq
   driver (Li RongQing)

 - Make intel_pstate always use HWP_DESIRED_PERF in passive mode (Rafael
   Wysocki)

 - Allow building the tegra124 cpufreq driver as a module (Aaron Kling)

 - Do minor cleanups for Rust cpufreq and cpumask APIs and fix MAINTAINERS
   entry for cpu.rs (Abhinav Ananthu, Ritvik Gupta, Lukas Bulwahn)

 - Clean up assorted cpufreq drivers (Arnd Bergmann, Dan Carpenter,
   Krzysztof Kozlowski, Sven Peter, Svyatoslav Ryhel, Lifeng Zheng)

 - Add the NEED_UPDATE_LIMITS flag to the CPPC cpufreq driver (Prashant
   Malani)

 - Fix minimum performance state label error in the amd-pstate driver
   documentation (Shouye Liu)

 - Add the CPUFREQ_GOV_STRICT_TARGET flag to the userspace cpufreq
   governor and explain HW coordination influence on it in the
   documentation (Shashank Balaji)

* pm-cpufreq: (27 commits)
  cpufreq: CPPC: Mark driver with NEED_UPDATE_LIMITS flag
  Documentation: amd-pstate:fix minimum performance state label error
  drivers: cpufreq: add Tegra114 support
  rust: cpumask: Replace `MaybeUninit` and `mem::zeroed` with `Opaque` APIs
  cpufreq: Exit governor when failed to start old governor
  cpufreq: Move the check of cpufreq_driver->get into cpufreq_verify_current_freq()
  cpufreq: Init policy->rwsem before it may be possibly used
  cpufreq: Initialize cpufreq-based frequency-invariance later
  cpufreq: Remove duplicate check in __cpufreq_offline()
  cpufreq: Contain scaling_cur_freq.attr in cpufreq_attrs
  cpufreq: intel_pstate: Add Granite Rapids support in no-HWP mode
  cpufreq: intel_pstate: Always use HWP_DESIRED_PERF in passive mode
  cpufreq: tegra124: Allow building as a module
  cpufreq: dt: Add register helper
  cpufreq: Export disable_cpufreq()
  cpufreq: armada-8k: Fix off by one in armada_8k_cpufreq_free_table()
  cpufreq: armada-8k: make both cpu masks static
  rust: cpufreq: use c_ types from kernel prelude
  rust: cpufreq: Ensure C ABI compatibility in all unsafe
  cpufreq: brcmstb-avs: Fully open-code compatible for grepping
  ...
This commit is contained in:
Rafael J. Wysocki
2025-07-22 17:24:59 +02:00
17 changed files with 137 additions and 142 deletions

View File

@@ -72,7 +72,7 @@ to manage each performance update behavior. ::
Lowest non- | | | |
linear perf ------>+-----------------------+ +-----------------------+
| | | |
| | Lowest perf ---->| |
| | Min perf ---->| |
| | | |
Lowest perf ------>+-----------------------+ +-----------------------+
| | | |

View File

@@ -398,7 +398,9 @@ policy limits change after that.
This governor does not do anything by itself. Instead, it allows user space
to set the CPU frequency for the policy it is attached to by writing to the
``scaling_setspeed`` attribute of that policy.
``scaling_setspeed`` attribute of that policy. Though the intention may be to
set an exact frequency for the policy, the actual frequency may vary depending
on hardware coordination, thermal and power limits, and other factors.
``schedutil``
-------------

View File

@@ -6256,7 +6256,7 @@ F: include/linux/cpuhotplug.h
F: include/linux/smpboot.h
F: kernel/cpu.c
F: kernel/smpboot.*
F: rust/helper/cpu.c
F: rust/helpers/cpu.c
F: rust/kernel/cpu.rs
CPU IDLE TIME MANAGEMENT FRAMEWORK

View File

@@ -28,7 +28,6 @@ config ARM_APPLE_SOC_CPUFREQ
tristate "Apple Silicon SoC CPUFreq support"
depends on ARCH_APPLE || (COMPILE_TEST && 64BIT)
select PM_OPP
default ARCH_APPLE
help
This adds the CPUFreq driver for Apple Silicon machines
(e.g. Apple M1).
@@ -238,7 +237,7 @@ config ARM_TEGRA20_CPUFREQ
This adds the CPUFreq driver support for Tegra20/30 SOCs.
config ARM_TEGRA124_CPUFREQ
bool "Tegra124 CPUFreq support"
tristate "Tegra124 CPUFreq support"
depends on ARCH_TEGRA || COMPILE_TEST
depends on CPUFREQ_DT
default ARCH_TEGRA

View File

@@ -103,7 +103,7 @@ static void armada_8k_cpufreq_free_table(struct freq_table *freq_tables)
{
int opps_index, nb_cpus = num_possible_cpus();
for (opps_index = 0 ; opps_index <= nb_cpus; opps_index++) {
for (opps_index = 0 ; opps_index < nb_cpus; opps_index++) {
int i;
/* If cpu_dev is NULL then we reached the end of the array */
@@ -132,7 +132,7 @@ static int __init armada_8k_cpufreq_init(void)
int ret = 0, opps_index = 0, cpu, nb_cpus;
struct freq_table *freq_tables;
struct device_node *node;
static struct cpumask cpus;
static struct cpumask cpus, shared_cpus;
node = of_find_matching_node_and_match(NULL, armada_8k_cpufreq_of_match,
NULL);
@@ -154,7 +154,6 @@ static int __init armada_8k_cpufreq_init(void)
* divisions of it).
*/
for_each_cpu(cpu, &cpus) {
struct cpumask shared_cpus;
struct device *cpu_dev;
struct clk *clk;

View File

@@ -765,7 +765,7 @@ static void brcm_avs_cpufreq_remove(struct platform_device *pdev)
}
static const struct of_device_id brcm_avs_cpufreq_match[] = {
{ .compatible = BRCM_AVS_CPU_DATA },
{ .compatible = "brcm,avs-cpu-data-mem" },
{ }
};
MODULE_DEVICE_TABLE(of, brcm_avs_cpufreq_match);

View File

@@ -26,14 +26,6 @@
#include <acpi/cppc_acpi.h>
/*
* This list contains information parsed from per CPU ACPI _CPC and _PSD
* structures: e.g. the highest and lowest supported performance, capabilities,
* desired performance, level requested etc. Depending on the share_type, not
* all CPUs will have an entry in the list.
*/
static LIST_HEAD(cpu_data_list);
static struct cpufreq_driver cppc_cpufreq_driver;
#ifdef CONFIG_ACPI_CPPC_CPUFREQ_FIE
@@ -352,7 +344,6 @@ static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu)
#if defined(CONFIG_ARM64) && defined(CONFIG_ENERGY_MODEL)
static DEFINE_PER_CPU(unsigned int, efficiency_class);
static void cppc_cpufreq_register_em(struct cpufreq_policy *policy);
/* Create an artificial performance state every CPPC_EM_CAP_STEP capacity unit. */
#define CPPC_EM_CAP_STEP (20)
@@ -488,7 +479,19 @@ static int cppc_get_cpu_cost(struct device *cpu_dev, unsigned long KHz,
return 0;
}
static int populate_efficiency_class(void)
static void cppc_cpufreq_register_em(struct cpufreq_policy *policy)
{
struct cppc_cpudata *cpu_data;
struct em_data_callback em_cb =
EM_ADV_DATA_CB(cppc_get_cpu_power, cppc_get_cpu_cost);
cpu_data = policy->driver_data;
em_dev_register_perf_domain(get_cpu_device(policy->cpu),
get_perf_level_count(policy), &em_cb,
cpu_data->shared_cpu_map, 0);
}
static void populate_efficiency_class(void)
{
struct acpi_madt_generic_interrupt *gicc;
DECLARE_BITMAP(used_classes, 256) = {};
@@ -503,7 +506,7 @@ static int populate_efficiency_class(void)
if (bitmap_weight(used_classes, 256) <= 1) {
pr_debug("Efficiency classes are all equal (=%d). "
"No EM registered", class);
return -EINVAL;
return;
}
/*
@@ -520,26 +523,11 @@ static int populate_efficiency_class(void)
index++;
}
cppc_cpufreq_driver.register_em = cppc_cpufreq_register_em;
return 0;
}
static void cppc_cpufreq_register_em(struct cpufreq_policy *policy)
{
struct cppc_cpudata *cpu_data;
struct em_data_callback em_cb =
EM_ADV_DATA_CB(cppc_get_cpu_power, cppc_get_cpu_cost);
cpu_data = policy->driver_data;
em_dev_register_perf_domain(get_cpu_device(policy->cpu),
get_perf_level_count(policy), &em_cb,
cpu_data->shared_cpu_map, 0);
}
#else
static int populate_efficiency_class(void)
static void populate_efficiency_class(void)
{
return 0;
}
#endif
@@ -567,8 +555,6 @@ static struct cppc_cpudata *cppc_cpufreq_get_cpu_data(unsigned int cpu)
goto free_mask;
}
list_add(&cpu_data->node, &cpu_data_list);
return cpu_data;
free_mask:
@@ -583,7 +569,6 @@ static void cppc_cpufreq_put_cpu_data(struct cpufreq_policy *policy)
{
struct cppc_cpudata *cpu_data = policy->driver_data;
list_del(&cpu_data->node);
free_cpumask_var(cpu_data->shared_cpu_map);
kfree(cpu_data);
policy->driver_data = NULL;
@@ -925,7 +910,7 @@ static struct freq_attr *cppc_cpufreq_attr[] = {
};
static struct cpufreq_driver cppc_cpufreq_driver = {
.flags = CPUFREQ_CONST_LOOPS,
.flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS,
.verify = cppc_verify_policy,
.target = cppc_cpufreq_set_target,
.get = cppc_cpufreq_get_rate,
@@ -954,24 +939,10 @@ static int __init cppc_cpufreq_init(void)
return ret;
}
static inline void free_cpu_data(void)
{
struct cppc_cpudata *iter, *tmp;
list_for_each_entry_safe(iter, tmp, &cpu_data_list, node) {
free_cpumask_var(iter->shared_cpu_map);
list_del(&iter->node);
kfree(iter);
}
}
static void __exit cppc_cpufreq_exit(void)
{
cpufreq_unregister_driver(&cppc_cpufreq_driver);
cppc_freq_invariance_exit();
free_cpu_data();
}
module_exit(cppc_cpufreq_exit);

View File

@@ -143,6 +143,7 @@ static const struct of_device_id blocklist[] __initconst = {
{ .compatible = "nvidia,tegra20", },
{ .compatible = "nvidia,tegra30", },
{ .compatible = "nvidia,tegra114", },
{ .compatible = "nvidia,tegra124", },
{ .compatible = "nvidia,tegra210", },
{ .compatible = "nvidia,tegra234", },

View File

@@ -329,6 +329,17 @@ static struct platform_driver dt_cpufreq_platdrv = {
};
module_platform_driver(dt_cpufreq_platdrv);
struct platform_device *cpufreq_dt_pdev_register(struct device *dev)
{
struct platform_device_info cpufreq_dt_devinfo = {};
cpufreq_dt_devinfo.name = "cpufreq-dt";
cpufreq_dt_devinfo.parent = dev;
return platform_device_register_full(&cpufreq_dt_devinfo);
}
EXPORT_SYMBOL_GPL(cpufreq_dt_pdev_register);
MODULE_ALIAS("platform:cpufreq-dt");
MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>");
MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");

View File

@@ -22,4 +22,6 @@ struct cpufreq_dt_platform_data {
int (*resume)(struct cpufreq_policy *policy);
};
struct platform_device *cpufreq_dt_pdev_register(struct device *dev);
#endif /* __CPUFREQ_DT_H__ */

View File

@@ -109,6 +109,8 @@ void disable_cpufreq(void)
{
off = 1;
}
EXPORT_SYMBOL_GPL(disable_cpufreq);
static DEFINE_MUTEX(cpufreq_governor_mutex);
bool have_governor_per_policy(void)
@@ -967,6 +969,7 @@ static struct attribute *cpufreq_attrs[] = {
&cpuinfo_min_freq.attr,
&cpuinfo_max_freq.attr,
&cpuinfo_transition_latency.attr,
&scaling_cur_freq.attr,
&scaling_min_freq.attr,
&scaling_max_freq.attr,
&affected_cpus.attr,
@@ -1095,10 +1098,6 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy)
return ret;
}
ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
if (ret)
return ret;
if (cpufreq_driver->bios_limit) {
ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
if (ret)
@@ -1284,6 +1283,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
goto err_free_real_cpus;
}
init_rwsem(&policy->rwsem);
freq_constraints_init(&policy->constraints);
policy->nb_min.notifier_call = cpufreq_notifier_min;
@@ -1306,7 +1307,6 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
}
INIT_LIST_HEAD(&policy->policy_list);
init_rwsem(&policy->rwsem);
spin_lock_init(&policy->transition_lock);
init_waitqueue_head(&policy->transition_wait);
INIT_WORK(&policy->update, handle_update);
@@ -1694,14 +1694,13 @@ static void __cpufreq_offline(unsigned int cpu, struct cpufreq_policy *policy)
return;
}
if (has_target())
if (has_target()) {
strscpy(policy->last_governor, policy->governor->name,
CPUFREQ_NAME_LEN);
else
policy->last_policy = policy->policy;
if (has_target())
cpufreq_exit_governor(policy);
} else {
policy->last_policy = policy->policy;
}
/*
* Perform the ->offline() during light-weight tear-down, as
@@ -1803,6 +1802,9 @@ static unsigned int cpufreq_verify_current_freq(struct cpufreq_policy *policy, b
{
unsigned int new_freq;
if (!cpufreq_driver->get)
return 0;
new_freq = cpufreq_driver->get(policy->cpu);
if (!new_freq)
return 0;
@@ -1925,10 +1927,7 @@ unsigned int cpufreq_get(unsigned int cpu)
guard(cpufreq_policy_read)(policy);
if (cpufreq_driver->get)
return __cpufreq_get(policy);
return 0;
return __cpufreq_get(policy);
}
EXPORT_SYMBOL(cpufreq_get);
@@ -2482,8 +2481,7 @@ int cpufreq_start_governor(struct cpufreq_policy *policy)
pr_debug("%s: for CPU %u\n", __func__, policy->cpu);
if (cpufreq_driver->get)
cpufreq_verify_current_freq(policy, false);
cpufreq_verify_current_freq(policy, false);
if (policy->governor->start) {
ret = policy->governor->start(policy);
@@ -2715,10 +2713,12 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
pr_debug("starting governor %s failed\n", policy->governor->name);
if (old_gov) {
policy->governor = old_gov;
if (cpufreq_init_governor(policy))
if (cpufreq_init_governor(policy)) {
policy->governor = NULL;
else
cpufreq_start_governor(policy);
} else if (cpufreq_start_governor(policy)) {
cpufreq_exit_governor(policy);
policy->governor = NULL;
}
}
return ret;
@@ -2944,15 +2944,6 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
cpufreq_driver = driver_data;
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
/*
* Mark support for the scheduler's frequency invariance engine for
* drivers that implement target(), target_index() or fast_switch().
*/
if (!cpufreq_driver->setpolicy) {
static_branch_enable_cpuslocked(&cpufreq_freq_invariance);
pr_debug("supports frequency invariance");
}
if (driver_data->setpolicy)
driver_data->flags |= CPUFREQ_CONST_LOOPS;
@@ -2983,6 +2974,15 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
hp_online = ret;
ret = 0;
/*
* Mark support for the scheduler's frequency invariance engine for
* drivers that implement target(), target_index() or fast_switch().
*/
if (!cpufreq_driver->setpolicy) {
static_branch_enable_cpuslocked(&cpufreq_freq_invariance);
pr_debug("supports frequency invariance");
}
pr_debug("driver %s up and running\n", driver_data->name);
goto out;

View File

@@ -134,6 +134,7 @@ static struct cpufreq_governor cpufreq_gov_userspace = {
.store_setspeed = cpufreq_set,
.show_setspeed = show_speed,
.owner = THIS_MODULE,
.flags = CPUFREQ_GOV_STRICT_TARGET,
};
MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>, "

View File

@@ -2775,6 +2775,8 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
X86_MATCH(INTEL_TIGERLAKE, core_funcs),
X86_MATCH(INTEL_SAPPHIRERAPIDS_X, core_funcs),
X86_MATCH(INTEL_EMERALDRAPIDS_X, core_funcs),
X86_MATCH(INTEL_GRANITERAPIDS_D, core_funcs),
X86_MATCH(INTEL_GRANITERAPIDS_X, core_funcs),
{}
};
MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
@@ -3249,8 +3251,8 @@ static int intel_cpufreq_update_pstate(struct cpufreq_policy *policy,
int max_pstate = policy->strict_target ?
target_pstate : cpu->max_perf_ratio;
intel_cpufreq_hwp_update(cpu, target_pstate, max_pstate, 0,
fast_switch);
intel_cpufreq_hwp_update(cpu, target_pstate, max_pstate,
target_pstate, fast_switch);
} else if (target_pstate != old_pstate) {
intel_cpufreq_perf_ctl_update(cpu, target_pstate, fast_switch);
}

View File

@@ -16,6 +16,10 @@
#include <linux/pm_opp.h>
#include <linux/types.h>
#include "cpufreq-dt.h"
static struct platform_device *tegra124_cpufreq_pdev;
struct tegra124_cpufreq_priv {
struct clk *cpu_clk;
struct clk *pllp_clk;
@@ -55,7 +59,6 @@ static int tegra124_cpufreq_probe(struct platform_device *pdev)
struct device_node *np __free(device_node) = of_cpu_device_node_get(0);
struct tegra124_cpufreq_priv *priv;
struct device *cpu_dev;
struct platform_device_info cpufreq_dt_devinfo = {};
int ret;
if (!np)
@@ -95,11 +98,7 @@ static int tegra124_cpufreq_probe(struct platform_device *pdev)
if (ret)
goto out_put_pllp_clk;
cpufreq_dt_devinfo.name = "cpufreq-dt";
cpufreq_dt_devinfo.parent = &pdev->dev;
priv->cpufreq_dt_pdev =
platform_device_register_full(&cpufreq_dt_devinfo);
priv->cpufreq_dt_pdev = cpufreq_dt_pdev_register(&pdev->dev);
if (IS_ERR(priv->cpufreq_dt_pdev)) {
ret = PTR_ERR(priv->cpufreq_dt_pdev);
goto out_put_pllp_clk;
@@ -173,6 +172,21 @@ disable_cpufreq:
return err;
}
static void tegra124_cpufreq_remove(struct platform_device *pdev)
{
struct tegra124_cpufreq_priv *priv = dev_get_drvdata(&pdev->dev);
if (!IS_ERR(priv->cpufreq_dt_pdev)) {
platform_device_unregister(priv->cpufreq_dt_pdev);
priv->cpufreq_dt_pdev = ERR_PTR(-ENODEV);
}
clk_put(priv->pllp_clk);
clk_put(priv->pllx_clk);
clk_put(priv->dfll_clk);
clk_put(priv->cpu_clk);
}
static const struct dev_pm_ops tegra124_cpufreq_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(tegra124_cpufreq_suspend,
tegra124_cpufreq_resume)
@@ -182,15 +196,16 @@ static struct platform_driver tegra124_cpufreq_platdrv = {
.driver.name = "cpufreq-tegra124",
.driver.pm = &tegra124_cpufreq_pm_ops,
.probe = tegra124_cpufreq_probe,
.remove = tegra124_cpufreq_remove,
};
static int __init tegra_cpufreq_init(void)
{
int ret;
struct platform_device *pdev;
if (!(of_machine_is_compatible("nvidia,tegra124") ||
of_machine_is_compatible("nvidia,tegra210")))
if (!(of_machine_is_compatible("nvidia,tegra114") ||
of_machine_is_compatible("nvidia,tegra124") ||
of_machine_is_compatible("nvidia,tegra210")))
return -ENODEV;
/*
@@ -201,15 +216,25 @@ static int __init tegra_cpufreq_init(void)
if (ret)
return ret;
pdev = platform_device_register_simple("cpufreq-tegra124", -1, NULL, 0);
if (IS_ERR(pdev)) {
tegra124_cpufreq_pdev = platform_device_register_simple("cpufreq-tegra124", -1, NULL, 0);
if (IS_ERR(tegra124_cpufreq_pdev)) {
platform_driver_unregister(&tegra124_cpufreq_platdrv);
return PTR_ERR(pdev);
return PTR_ERR(tegra124_cpufreq_pdev);
}
return 0;
}
module_init(tegra_cpufreq_init);
static void __exit tegra_cpufreq_module_exit(void)
{
if (!IS_ERR_OR_NULL(tegra124_cpufreq_pdev))
platform_device_unregister(tegra124_cpufreq_pdev);
platform_driver_unregister(&tegra124_cpufreq_platdrv);
}
module_exit(tegra_cpufreq_module_exit);
MODULE_AUTHOR("Tuomas Tynkkynen <ttynkkynen@nvidia.com>");
MODULE_DESCRIPTION("cpufreq driver for NVIDIA Tegra124");
MODULE_LICENSE("GPL");

View File

@@ -139,7 +139,6 @@ struct cppc_perf_fb_ctrs {
/* Per CPU container for runtime CPPC management. */
struct cppc_cpudata {
struct list_head node;
struct cppc_perf_caps perf_caps;
struct cppc_perf_ctrls perf_ctrls;
struct cppc_perf_fb_ctrs perf_fb_ctrs;

View File

@@ -1061,7 +1061,7 @@ impl<T: Driver> Registration<T> {
///
/// - This function may only be called from the cpufreq C infrastructure.
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int {
unsafe extern "C" fn init_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
from_result(|| {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
@@ -1094,7 +1094,7 @@ impl<T: Driver> Registration<T> {
///
/// - This function may only be called from the cpufreq C infrastructure.
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int {
unsafe extern "C" fn online_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
from_result(|| {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
@@ -1109,9 +1109,7 @@ impl<T: Driver> Registration<T> {
///
/// - This function may only be called from the cpufreq C infrastructure.
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn offline_callback(
ptr: *mut bindings::cpufreq_policy,
) -> kernel::ffi::c_int {
unsafe extern "C" fn offline_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
from_result(|| {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
@@ -1126,9 +1124,7 @@ impl<T: Driver> Registration<T> {
///
/// - This function may only be called from the cpufreq C infrastructure.
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn suspend_callback(
ptr: *mut bindings::cpufreq_policy,
) -> kernel::ffi::c_int {
unsafe extern "C" fn suspend_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
from_result(|| {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
@@ -1143,7 +1139,7 @@ impl<T: Driver> Registration<T> {
///
/// - This function may only be called from the cpufreq C infrastructure.
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> kernel::ffi::c_int {
unsafe extern "C" fn resume_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
from_result(|| {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
@@ -1171,9 +1167,7 @@ impl<T: Driver> Registration<T> {
///
/// - This function may only be called from the cpufreq C infrastructure.
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn verify_callback(
ptr: *mut bindings::cpufreq_policy_data,
) -> kernel::ffi::c_int {
unsafe extern "C" fn verify_callback(ptr: *mut bindings::cpufreq_policy_data) -> c_int {
from_result(|| {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
@@ -1188,9 +1182,7 @@ impl<T: Driver> Registration<T> {
///
/// - This function may only be called from the cpufreq C infrastructure.
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn setpolicy_callback(
ptr: *mut bindings::cpufreq_policy,
) -> kernel::ffi::c_int {
unsafe extern "C" fn setpolicy_callback(ptr: *mut bindings::cpufreq_policy) -> c_int {
from_result(|| {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
@@ -1207,9 +1199,9 @@ impl<T: Driver> Registration<T> {
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn target_callback(
ptr: *mut bindings::cpufreq_policy,
target_freq: u32,
relation: u32,
) -> kernel::ffi::c_int {
target_freq: c_uint,
relation: c_uint,
) -> c_int {
from_result(|| {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
@@ -1226,8 +1218,8 @@ impl<T: Driver> Registration<T> {
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn target_index_callback(
ptr: *mut bindings::cpufreq_policy,
index: u32,
) -> kernel::ffi::c_int {
index: c_uint,
) -> c_int {
from_result(|| {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
@@ -1249,8 +1241,8 @@ impl<T: Driver> Registration<T> {
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn fast_switch_callback(
ptr: *mut bindings::cpufreq_policy,
target_freq: u32,
) -> kernel::ffi::c_uint {
target_freq: c_uint,
) -> c_uint {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
let policy = unsafe { Policy::from_raw_mut(ptr) };
@@ -1263,10 +1255,10 @@ impl<T: Driver> Registration<T> {
///
/// - This function may only be called from the cpufreq C infrastructure.
unsafe extern "C" fn adjust_perf_callback(
cpu: u32,
min_perf: usize,
target_perf: usize,
capacity: usize,
cpu: c_uint,
min_perf: c_ulong,
target_perf: c_ulong,
capacity: c_ulong,
) {
// SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
@@ -1284,8 +1276,8 @@ impl<T: Driver> Registration<T> {
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn get_intermediate_callback(
ptr: *mut bindings::cpufreq_policy,
index: u32,
) -> kernel::ffi::c_uint {
index: c_uint,
) -> c_uint {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
let policy = unsafe { Policy::from_raw_mut(ptr) };
@@ -1305,8 +1297,8 @@ impl<T: Driver> Registration<T> {
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn target_intermediate_callback(
ptr: *mut bindings::cpufreq_policy,
index: u32,
) -> kernel::ffi::c_int {
index: c_uint,
) -> c_int {
from_result(|| {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.
@@ -1325,7 +1317,7 @@ impl<T: Driver> Registration<T> {
/// # Safety
///
/// - This function may only be called from the cpufreq C infrastructure.
unsafe extern "C" fn get_callback(cpu: u32) -> kernel::ffi::c_uint {
unsafe extern "C" fn get_callback(cpu: c_uint) -> c_uint {
// SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
@@ -1351,7 +1343,7 @@ impl<T: Driver> Registration<T> {
///
/// - This function may only be called from the cpufreq C infrastructure.
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn bios_limit_callback(cpu: i32, limit: *mut u32) -> kernel::ffi::c_int {
unsafe extern "C" fn bios_limit_callback(cpu: c_int, limit: *mut c_uint) -> c_int {
// SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
let cpu_id = unsafe { CpuId::from_i32_unchecked(cpu) };
@@ -1371,8 +1363,8 @@ impl<T: Driver> Registration<T> {
/// - The pointer arguments must be valid pointers.
unsafe extern "C" fn set_boost_callback(
ptr: *mut bindings::cpufreq_policy,
state: i32,
) -> kernel::ffi::c_int {
state: c_int,
) -> c_int {
from_result(|| {
// SAFETY: The `ptr` is guaranteed to be valid by the contract with the C code for the
// lifetime of `policy`.

View File

@@ -14,9 +14,6 @@ use crate::{
#[cfg(CONFIG_CPUMASK_OFFSTACK)]
use core::ptr::{self, NonNull};
#[cfg(not(CONFIG_CPUMASK_OFFSTACK))]
use core::mem::MaybeUninit;
use core::ops::{Deref, DerefMut};
/// A CPU Mask.
@@ -239,10 +236,7 @@ impl CpumaskVar {
},
#[cfg(not(CONFIG_CPUMASK_OFFSTACK))]
// SAFETY: FFI type is valid to be zero-initialized.
//
// INVARIANT: The associated memory is freed when the `CpumaskVar` goes out of scope.
mask: unsafe { core::mem::zeroed() },
mask: Cpumask(Opaque::zeroed()),
})
}
@@ -266,10 +260,7 @@ impl CpumaskVar {
NonNull::new(ptr.cast()).ok_or(AllocError)?
},
#[cfg(not(CONFIG_CPUMASK_OFFSTACK))]
// SAFETY: Guaranteed by the safety requirements of the function.
//
// INVARIANT: The associated memory is freed when the `CpumaskVar` goes out of scope.
mask: unsafe { MaybeUninit::uninit().assume_init() },
mask: Cpumask(Opaque::uninit()),
})
}