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 分配的表