cpufreq的governor中performance实际上是最简单粗暴的,因为他直接将freq上升到最高
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/module.h>
// 回调函数响应具体的事件
static int cpufreq_governor_performance(struct cpufreq_policy *policy,
unsigned int event)
{
switch (event) {
case CPUFREQ_GOV_START:
case CPUFREQ_GOV_LIMITS:
pr_debug("setting to %u kHz because of event %u\n", policy->max, event);
__cpufreq_driver_target(policy, policy->max,CPUFREQ_RELATION_H);
break;
default:
break;
}
return 0;
}
#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE_MODULE
static
#endif
struct cpufreq_governor cpufreq_gov_performance = {
.name = "performance",
.governor = cpufreq_governor_performance,
.owner = THIS_MODULE,
};
static int __init cpufreq_gov_performance_init(void)
{
return cpufreq_register_governor(&cpufreq_gov_performance);
}
static void __exit cpufreq_gov_performance_exit(void)
{
cpufreq_unregister_governor(&cpufreq_gov_performance);
}
MODULE_AUTHOR("xxxxxx");
MODULE_DESCRIPTION("CPUfreq policy governor 'performance'");
MODULE_LICENSE("GPL");
// 序号是5
fs_initcall(cpufreq_gov_performance_init);
module_exit(cpufreq_gov_performance_exit);
注册和移除governor都是添加或者从内核的链表中添加或者移除
//将governor注册到cpufreq core中之后才能通过policy的governor和policy相互关联,才能被使用
int cpufreq_register_governor(struct cpufreq_governor *governor)
{
int err;
if (!governor)
return -EINVAL;
if (cpufreq_disabled())
return -ENODEV;
// mutex互斥体用来保护较长的临界区
mutex_lock(&cpufreq_governor_mutex);
governor->initialized = 0;
err = -EBUSY;
if (!find_governor(governor->name)) {
err = 0;
// 将governor添加到governor的list里面去
// 核心层定义了一个全局链表变量,cpufreq_governor_list
list_add(&governor->governor_list, &cpufreq_governor_list);
}
mutex_unlock(&cpufreq_governor_mutex);
return err;
}
EXPORT_SYMBOL_GPL(cpufreq_register_governor);
void cpufreq_unregister_governor(struct cpufreq_governor *governor)
{
struct cpufreq_policy *policy;
unsigned long flags;
if (!governor)
return;
if (cpufreq_disabled())
return;
/* clear last_governor for all inactive policies */
read_lock_irqsave(&cpufreq_driver_lock, flags);
for_each_inactive_policy(policy) {
if (!strcmp(policy->last_governor, governor->name)) {
policy->governor = NULL;
strcpy(policy->last_governor, "\0");
}
}
read_unlock_irqrestore(&cpufreq_driver_lock, flags);
mutex_lock(&cpufreq_governor_mutex);
list_del(&governor->governor_list);
mutex_unlock(&cpufreq_governor_mutex);
return;
}
EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
至于后面的接受事件的回调函数。。。