CPUFreq 核心和 CPUFreq 通知器概述

作者

1. 一般信息

CPUFreq 核心代码位于 drivers/cpufreq/cpufreq.c。此 cpufreq 代码为 CPUFreq 架构驱动程序(执行实际频率转换的代码段)以及“通知器”提供了标准化的接口。这些通知器是设备驱动程序或内核的其他部分,它们需要被告知策略更改(例如 ACPI 等热管理模块)或所有频率更改(例如时序代码),甚至可能需要强制某些速度限制(例如 ARM 架构上的 LCD 驱动程序)。此外,内核“常量”loops_per_jiffy 会在此处根据频率更改进行更新。

cpufreq 策略的引用计数由 cpufreq_cpu_get 和 cpufreq_cpu_put 完成,它们确保 cpufreq 驱动程序正确注册到核心,并且在调用 cpufreq_put_cpu 之前不会被卸载。这还确保了相关的 cpufreq 策略在使用时不会被释放。

2. CPUFreq 通知器

CPUFreq 通知器遵循标准的内核通知器接口。有关通知器的详细信息,请参见 linux/include/linux/notifier.h。

有两种不同的 CPUFreq 通知器——策略通知器和转换通知器。

2.1 CPUFreq 策略通知器

当创建或删除新策略时,这些通知器会收到通知。

阶段在通知器的第二个参数中指定。当策略首次创建时,阶段为 CPUFREQ_CREATE_POLICY;当策略被移除时,阶段为 CPUFREQ_REMOVE_POLICY。

第三个参数,一个 void *pointer,指向一个 struct cpufreq_policy,其中包含多个值,包括 min、max(新策略的最低和最高频率(以 kHz 为单位))。

2.2 CPUFreq 转换通知器

当 CPUfreq 驱动程序切换 CPU 核心频率且此更改不涉及任何外部影响时,对于策略中的每个在线 CPU,这些通知器会收到两次通知。

第二个参数指定阶段——CPUFREQ_PRECHANGE 或 CPUFREQ_POSTCHANGE。

第三个参数是一个 struct cpufreq_freqs,包含以下值:

policy

指向 struct cpufreq_policy 的指针

old

旧频率

new

新频率

flags

cpufreq 驱动程序的标志

3. 使用工作性能点 (OPP) 生成 CPUFreq 表

有关 OPP 的详细信息,请参阅 工作性能点 (OPP) 库

dev_pm_opp_init_cpufreq_table -

此函数提供了一个即用型转换例程,用于将 OPP 层关于可用频率的内部信息转换为可直接提供给 cpufreq 的格式。

警告

请勿在中断上下文中使用此函数。

示例

soc_pm_init()
{
       /* Do things */
       r = dev_pm_opp_init_cpufreq_table(dev, &freq_table);
       if (!r)
               policy->freq_table = freq_table;
       /* Do other things */
}

注意

此函数仅在除了 CONFIG_PM_OPP 之外还启用了 CONFIG_CPU_FREQ 时才可用。

dev_pm_opp_free_cpufreq_table

释放由 dev_pm_opp_init_cpufreq_table 分配的表