设备频率调节¶
简介¶
此框架为任意设备的动态电压和频率切换提供了一个标准的内核接口。
它通过 sysfs 文件公开用于调整频率的控件,这些文件与 cpufreq 子系统类似。
可以测量当前使用情况的设备可以通过调速器自动调整其频率。
API¶
设备驱动程序需要初始化一个 devfreq_profile
并调用 devfreq_add_device()
函数来创建一个 devfreq
实例。
-
struct devfreq_dev_status¶
从 devfreq 用户设备提供给调速器的数据。表示性能统计信息。
定义:
struct devfreq_dev_status {
unsigned long total_time;
unsigned long busy_time;
unsigned long current_frequency;
void *private_data;
};
成员
total_time
此 devfreq_dev_status 实例表示的总时间
busy_time
设备在 total_time 中处于工作状态的时间。
current_frequency
工作频率。
private_data
devfreq 框架未指定的条目。设备和特定调速器可以具有它们自己的带有 private_data 的协议。但是,由于这是特定于调速器的,因此使用此项的调速器将仅与知道此项的设备兼容。
-
struct devfreq_dev_profile¶
Devfreq 的用户设备配置文件
定义:
struct devfreq_dev_profile {
unsigned long initial_freq;
unsigned int polling_ms;
enum devfreq_timer timer;
int (*target)(struct device *dev, unsigned long *freq, u32 flags);
int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat);
int (*get_cur_freq)(struct device *dev, unsigned long *freq);
void (*exit)(struct device *dev);
unsigned long *freq_table;
unsigned int max_state;
bool is_cooling_device;
};
成员
initial_freq
调用
devfreq_add_device()
时的运行频率。polling_ms
轮询间隔(以毫秒为单位)。0 禁用轮询。
timer
计时器类型是可延迟计时器或延迟计时器。
target
设备应将其运行频率设置为 freq 或高于 freq 的最低值。如果 freq 高于任何可操作的频率,则设置为最大值。在返回之前,target 函数应将 freq 设置为当前频率。“flags”参数的可能值在上面用“DEVFREQ_FLAG_*”宏进行了解释。
get_dev_status
设备应向 devfreq 提供当前的性能状态。建议调速器不要直接使用此项。相反,建议调速器使用 devfreq_update_stats() 以及 devfreq.last_status。
get_cur_freq
设备应提供其当前运行的频率。
exit
当 devfreq 由于错误或从
devfreq_remove_device()
调用而删除 devfreq 对象时,调用的可选回调。如果用户在 notifier-head 中注册了 devfreq->nb,则此时取消注册它。freq_table
可选的支持统计信息的频率列表,并且 freq_table 必须按升序生成。
max_state
freq_table 的大小。
is_cooling_device
一个不言自明的布尔值,赋予设备冷却效果属性。
-
struct devfreq_stats¶
devfreq 设备行为的统计信息
定义:
struct devfreq_stats {
unsigned int total_trans;
unsigned int *trans_table;
u64 *time_in_state;
u64 last_update;
};
成员
total_trans
devfreq 转换的次数。
trans_table
devfreq 转换的统计信息。
time_in_state
devfreq 状态的统计信息。
last_update
上次更新统计信息的时间。
-
struct devfreq¶
设备 devfreq 结构
定义:
struct devfreq {
struct list_head node;
struct mutex lock;
struct device dev;
struct devfreq_dev_profile *profile;
const struct devfreq_governor *governor;
struct opp_table *opp_table;
struct notifier_block nb;
struct delayed_work work;
unsigned long *freq_table;
unsigned int max_state;
unsigned long previous_freq;
struct devfreq_dev_status last_status;
void *data;
void *governor_data;
struct dev_pm_qos_request user_min_freq_req;
struct dev_pm_qos_request user_max_freq_req;
unsigned long scaling_min_freq;
unsigned long scaling_max_freq;
bool stop_polling;
unsigned long suspend_freq;
unsigned long resume_freq;
atomic_t suspend_count;
struct devfreq_stats stats;
struct srcu_notifier_head transition_notifier_list;
struct thermal_cooling_device *cdev;
struct notifier_block nb_min;
struct notifier_block nb_max;
};
成员
node
列表节点 - 包含已注册的具有 devfreq 的设备。
lock
一个互斥锁,用于保护对 devfreq 的访问。
dev
由 devfreq 类注册的设备。dev.parent 是使用 devfreq 的设备。
profile
设备特定的 devfreq 配置文件
governor
如何根据使用情况选择频率的方法。
opp_table
引用 dev.parent 的 OPP 表(如果存在)。
nb
用于通知 devfreq 对象应重新评估可操作频率的通知程序块。Devfreq 用户可以使用 devfreq.nb 到相应的寄存器通知程序调用链。
work
用于负载监控的延迟工作。
freq_table
devfreq 驱动程序使用的当前频率表。
max_state
频率表中存在的条目数。
previous_freq
先前配置的频率值。
last_status
devfreq 用户设备信息、性能统计信息
data
devfreq 驱动程序传递给调速器,调速器不应更改它。
governor_data
调速器的私有数据,devfreq 核心不会触及它。
user_min_freq_req
来自用户(通过 sysfs)的 PM QoS 最低频率请求
user_max_freq_req
来自用户(通过 sysfs)的 PM QoS 最高频率请求
scaling_min_freq
限制 OPP 接口请求的最低频率
scaling_max_freq
限制 OPP 接口请求的最高频率
stop_polling
设备的 devfreq 轮询状态。
suspend_freq
在挂起阶段设置的设备的频率。
resume_freq
在恢复阶段设置的设备的频率。
suspend_count
设备的挂起请求计数器。
stats
devfreq 设备行为的统计信息
transition_notifier_list
DEVFREQ_TRANSITION_NOTIFIER 通知程序的列表头
cdev
如果 devfreq 具有冷却属性,则为冷却设备指针
nb_min
DEV_PM_QOS_MIN_FREQUENCY 的通知程序块
nb_max
DEV_PM_QOS_MAX_FREQUENCY 的通知程序块
描述
此结构存储给定设备的 devfreq 信息。
请注意,当调速器在其函数中访问 struct devfreq
中的条目时(除了 struct devfreq_governor 中定义的回调上下文之外),调速器应使用 struct devfreq
中的 struct mutex 锁来保护其访问。调速器可以使用此互斥锁来保护其在 void *data
中的私有数据。
-
struct devfreq_simple_ondemand_data¶
馈送到
struct devfreq
和 devfreq_add_device 的void *data
定义:
struct devfreq_simple_ondemand_data {
unsigned int upthreshold;
unsigned int downdifferential;
};
成员
upthreshold
如果负载超过此值,则频率会跳跃。指定 0 以使用默认值。有效值 = 0 到 100。
downdifferential
如果负载低于 upthreshold - downdifferential,则调速器可能会考虑降低频率。指定 0 以使用默认值。有效值 = 0 到 100。downdifferential < upthreshold 必须成立。
描述
如果馈送到调速器的 devfreq_simple_ondemand_data 指针为 NULL,则调速器使用默认值。
-
struct devfreq_passive_data¶
馈送到
struct devfreq
和 devfreq_add_device 的void *data
定义:
struct devfreq_passive_data {
struct devfreq *parent;
int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
enum devfreq_parent_dev_type parent_type;
struct devfreq *this;
struct notifier_block nb;
struct list_head cpu_data_list;
};
成员
parent
父设备的 devfreq 实例。
get_target_freq
可选回调,返回使用被动调速器的设备的所需运行频率。当被动调速器应通过使用除被动调速器以外的调速器的父 devfreq 设备的新频率来决定下一个频率时,会调用该回调。如果 devfreq 设备具有确定下一个频率的特定方法,则应使用此回调。
parent_type
设备的父类型。
this
自身设备的 devfreq 实例。
nb
DEVFREQ_TRANSITION_NOTIFIER 或 CPUFREQ_TRANSITION_NOTIFIER 列表的通知程序块。
cpu_data_list
所有 cpufreq_policy 的 cpu 频率数据列表。
描述
devfreq_passive_data 必须设置具有除被动调速器以外的调速器的父设备的 devfreq 实例。但是,不需要初始化“this”和“nb”字段,因为 devfreq 核心会处理它们。
-
struct devfreq_event_dev¶
devfreq-event 设备
定义:
struct devfreq_event_dev {
struct list_head node;
struct device dev;
struct mutex lock;
u32 enable_count;
const struct devfreq_event_desc *desc;
};
成员
node
包含已注册的 devfreq-event 设备。
dev
由 devfreq-event 类注册的设备。dev.parent 是使用 devfreq-event 的设备。
lock
一个互斥锁,用于保护对 devfreq-event 的访问。
enable_count
已调用的 enable 函数的数量。
desc
devfreq-event 设备的描述。
描述
此结构包含 devfreq-event 设备信息。
-
struct devfreq_event_data¶
devfreq-event 数据
定义:
struct devfreq_event_data {
unsigned long load_count;
unsigned long total_count;
};
成员
load_count
给定期间的 devfreq-event 设备的负载计数。
total_count
给定期间的 devfreq-event 设备的总计数。每个计数可以表示一个时钟周期、一个时间单位(纳秒/微秒/...)或设备驱动程序所需的任何内容。通常,利用率是 load_count / total_count。
描述
此结构包含轮询期间的 devfreq-event 设备数据。
-
struct devfreq_event_ops¶
devfreq-event 设备的操作
定义:
struct devfreq_event_ops {
int (*enable)(struct devfreq_event_dev *edev);
int (*disable)(struct devfreq_event_dev *edev);
int (*reset)(struct devfreq_event_dev *edev);
int (*set_event)(struct devfreq_event_dev *edev);
int (*get_event)(struct devfreq_event_dev *edev, struct devfreq_event_data *edata);
};
成员
enable
启用 devfreq-event 设备。
disable
禁用 devfreq-event 设备。
reset
重置 devfreq-event 设备的所有设置。
set_event
为 devfreq-event 设备设置特定的事件类型。
get_event
获取具有特定事件类型的 devfreq-event 设备的结果。
描述
此结构包含可由 devfreq-event 设备驱动程序实现的 devfreq-event 设备操作。
-
struct devfreq_event_desc¶
devfreq-event 设备的描述符
定义:
struct devfreq_event_desc {
const char *name;
u32 event_type;
void *driver_data;
const struct devfreq_event_ops *ops;
};
成员
name
devfreq-event 设备的名称。
event_type
由驱动程序确定和使用的事件类型
driver_data
devfreq-event 驱动程序的私有数据。
ops
控制 devfreq-event 设备的操作。
描述
每个 devfreq-event 设备都用此结构描述。此结构包含 devfreq-event 设备的各种数据。event_type 描述了将在寄存器中计数的内容。它可以选择计数例如读取请求、以字节为单位的写入数据等。完整的支持类型列表位于以下 specyfic 标头中:include/dt-bindings/pmu/。
-
void devfreq_get_freq_range(struct devfreq *devfreq, unsigned long *min_freq, unsigned long *max_freq)¶
获取当前的频率范围
参数
struct devfreq *devfreq
devfreq 实例
unsigned long *min_freq
最小频率
unsigned long *max_freq
最大频率
描述
这考虑了所有约束。
参数
struct devfreq *devfreq
devfreq 实例
unsigned long freq
更新目标频率
参数
struct devfreq *devfreq
devfreq 实例。
unsigned long freq
父设备的新频率。此参数仅用于使用被动调速器的 devfreq 设备。
注意
- 在调用 devfreq_update_target 之前锁定 devfreq->lock。此函数
应仅由
update_devfreq()
和 devfreq 调速器使用。
参数
struct devfreq *devfreq
devfreq 实例。
注意
- 在调用 update_devfreq 之前锁定 devfreq->lock
此函数导出给调速器使用。
参数
struct devfreq *devfreq
devfreq 实例。
描述
用于启动 devfreq 设备负载监控的辅助函数。默认情况下,可延迟定时器用于负载监控。但是,用户可以使用 devfreq_dev_profile 中的 “timer” 类型更改此行为。当将设备添加到 devfreq 框架时,响应生成的 DEVFREQ_GOV_START 事件,devfreq 调速器将调用此函数。
参数
struct devfreq *devfreq
devfreq 实例。
描述
用于停止 devfreq 设备负载监控的辅助函数。当设备从 devfreq 框架中移除时,响应 DEVFREQ_GOV_STOP 事件从调速器调用的函数。
参数
struct devfreq *devfreq
devfreq 实例。
描述
用于暂停 devfreq 设备负载监控的辅助函数。响应 DEVFREQ_GOV_SUSPEND 事件或当轮询间隔设置为零时从调速器调用的函数。
注意
尽管此函数与 devfreq_monitor_stop()
相同,但有意保持分开,以便为收集转换统计信息提供钩子。
参数
struct devfreq *devfreq
devfreq 实例。
描述
用于恢复 devfreq 设备负载监控的辅助函数。响应 DEVFREQ_GOV_RESUME 事件或当轮询间隔设置为非零时从调速器调用的函数。
参数
struct devfreq *devfreq
devfreq 实例。
unsigned int *delay
要设置的新轮询间隔。
描述
用于设置新的负载监控轮询间隔的辅助函数。响应 DEVFREQ_GOV_UPDATE_INTERVAL 事件从调速器调用的函数。
-
struct devfreq *devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile, const char *governor_name, void *data)¶
向设备添加 devfreq 功能
参数
struct device *dev
要添加 devfreq 功能的设备。
struct devfreq_dev_profile *profile
运行 devfreq 的特定于设备的配置文件。
const char *governor_name
选择频率的策略的名称。
void *data
devfreq 驱动程序传递给调速器,调速器不应更改它。
-
struct devfreq *devm_devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile, const char *governor_name, void *data)¶
资源管理的
devfreq_add_device()
参数
struct device *dev
要添加 devfreq 功能的设备。
struct devfreq_dev_profile *profile
运行 devfreq 的特定于设备的配置文件。
const char *governor_name
选择频率的策略的名称。
void *data
devfreq 驱动程序传递给调速器,调速器不应更改它。
描述
此函数使用设备资源管理自动管理 devfreq 设备的内存,并简化 devfreq 设备内存的释放操作。
-
void devm_devfreq_remove_device(struct device *dev, struct devfreq *devfreq)¶
资源管理的
devfreq_remove_device()
参数
struct device *dev
从中移除 devfreq 功能的设备。
struct devfreq *devfreq
要移除的 devfreq 实例
参数
struct devfreq *devfreq
要挂起的 devfreq 实例
描述
此函数旨在由持有 devfreq 的设备驱动程序的 pm 回调(例如,runtime_suspend,suspend)调用。
参数
struct devfreq *devfreq
要恢复的 devfreq 实例
描述
此函数旨在由持有 devfreq 的设备驱动程序的 pm 回调(例如,runtime_resume,resume)调用。
-
int devfreq_add_governor(struct devfreq_governor *governor)¶
添加 devfreq governor
参数
struct devfreq_governor *governor
要添加的 devfreq governor
-
int devm_devfreq_add_governor(struct device *dev, struct devfreq_governor *governor)¶
添加 devfreq governor
参数
struct device *dev
添加 devfreq governor 的设备
struct devfreq_governor *governor
要添加的 devfreq governor
描述
这是 devfreq_add_governor()
的资源管理变体。
-
int devfreq_remove_governor(struct devfreq_governor *governor)¶
从设备中移除 devfreq 功能。
参数
struct devfreq_governor *governor
要移除的 devfreq governor
-
struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags)¶
辅助函数,用于获取给定给目标回调的频率值的正确 OPP。
参数
struct device *dev
devfreq 用户设备。(devfreq 的父级)
unsigned long *freq
给定给目标函数的频率
u32 flags
从 devfreq 框架传递的标志。
描述
调用者在使用后需要调用 dev_pm_opp_put() 来释放返回的 OPP。
-
int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq)¶
辅助函数,用于在 OPP 可用性发生任何变化时通知 devfreq。
参数
struct device *dev
devfreq 用户设备。(devfreq 的父级)
struct devfreq *devfreq
devfreq 对象。
-
int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq)¶
辅助函数,用于停止在 OPP 可用性发生任何变化时通知 devfreq。
参数
struct device *dev
devfreq 用户设备。(devfreq 的父级)
struct devfreq *devfreq
devfreq 对象。
描述
在 devfreq_dev_profile 的 exit() 回调中,如果使用了 devfreq_recommended_opp,则必须包含此项。
参数
struct device *dev
devfreq 用户设备。(devfreq 的父级)
struct devfreq *devfreq
devfreq 对象。
参数
struct device *dev
devfreq 用户设备。(devfreq 的父级)
struct devfreq *devfreq
devfreq 对象。
-
int devfreq_register_notifier(struct devfreq *devfreq, struct notifier_block *nb, unsigned int list)¶
向 devfreq 注册驱动程序
参数
struct devfreq *devfreq
devfreq 对象。
struct notifier_block *nb
要注册的通知器块。
unsigned int list
DEVFREQ_TRANSITION_NOTIFIER。
-
int devm_devfreq_register_notifier(struct device *dev, struct devfreq *devfreq, struct notifier_block *nb, unsigned int list)¶
参数
struct device *dev
devfreq 用户设备。(devfreq 的父级)
struct devfreq *devfreq
devfreq 对象。
struct notifier_block *nb
要注销的通知器块。
unsigned int list
DEVFREQ_TRANSITION_NOTIFIER。
描述
-
void devm_devfreq_unregister_notifier(struct device *dev, struct devfreq *devfreq, struct notifier_block *nb, unsigned int list)¶
参数
struct device *dev
devfreq 用户设备。(devfreq 的父级)
struct devfreq *devfreq
devfreq 对象。
struct notifier_block *nb
要注销的通知器块。
unsigned int list
DEVFREQ_TRANSITION_NOTIFIER。
描述
资源管理的 devfreq_unregister_notifier()
-
int devfreq_event_enable_edev(struct devfreq_event_dev *edev)¶
启用 devfreq-event 设备并增加 devfreq-event 设备的 enable_count。
参数
struct devfreq_event_dev *edev
devfreq-event 设备
描述
请注意,此函数会增加 enable_count 并启用 devfreq-event 设备。devfreq-event 设备应在 devfreq 设备使用之前启用。
-
int devfreq_event_disable_edev(struct devfreq_event_dev *edev)¶
禁用 devfreq-event 设备并减少 devfreq-event 设备的 enable_count。
参数
struct devfreq_event_dev *edev
devfreq-event 设备
描述
请注意,此函数会减少 enable_count 并禁用 devfreq-event 设备。禁用 devfreq-event 设备后,devfreq 设备将无法使用 devfreq-event 设备进行 get/set/reset 操作。
-
bool devfreq_event_is_enabled(struct devfreq_event_dev *edev)¶
检查 devfreq-event 设备是否已启用。
参数
struct devfreq_event_dev *edev
devfreq-event 设备
描述
请注意,此函数检查 devfreq-event 设备是否已启用。如果返回 true,则 devfreq-event 设备已启用。如果返回 false,则 devfreq-event 设备已禁用。
-
int devfreq_event_set_event(struct devfreq_event_dev *edev)¶
设置 devfreq-event 设备的事件以启动。
参数
struct devfreq_event_dev *edev
devfreq-event 设备
描述
请注意,此函数将事件设置为 devfreq-event 设备以启动,从而获取可能是各种事件类型的事件数据。
-
int devfreq_event_get_event(struct devfreq_event_dev *edev, struct devfreq_event_data *edata)¶
从 devfreq-event 设备获取 {load|total}_count。
参数
struct devfreq_event_dev *edev
devfreq-event 设备
struct devfreq_event_data *edata
devfreq-event 设备的计算数据
描述
请注意,此函数在停止 devfreq-event 设备的整个序列进度后,从 devfreq-event 设备获取计算的事件数据。
-
int devfreq_event_reset_event(struct devfreq_event_dev *edev)¶
重置 devfreq-event 设备的所有操作。
参数
struct devfreq_event_dev *edev
devfreq-event 设备
描述
请注意,此函数会停止 devfreq-event 设备的所有操作,并重置当前事件数据,使 devfreq-event 设备进入初始状态。
-
struct devfreq_event_dev *devfreq_event_get_edev_by_phandle(struct device *dev, const char *phandle_name, int index)¶
从设备树获取 devfreq-event 设备。
参数
struct device *dev
指向给定设备的指针
const char *phandle_name
保存 phandle 值的属性名称
int index
devfreq-event 设备列表的索引
描述
请注意,此函数返回 devfreq-event 设备的指针。
-
int devfreq_event_get_edev_count(struct device *dev, const char *phandle_name)¶
获取 devfreq-event 设备的计数
参数
struct device *dev
指向给定设备的指针
const char *phandle_name
保存 phandle 值的属性名称
描述
请注意,此函数返回 devfreq-event 设备的计数。
-
struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev, struct devfreq_event_desc *desc)¶
添加新的 devfreq 事件设备。
参数
struct device *dev
拥有要创建的 devfreq 事件设备的设备
struct devfreq_event_desc *desc
devfreq 事件设备的描述符,其中包含 devfreq 事件设备的基本数据。
描述
请注意,此函数将新的 devfreq 事件设备添加到 devfreq 事件类列表,并注册 devfreq 事件设备的设备。
-
int devfreq_event_remove_edev(struct devfreq_event_dev *edev)¶
移除已注册的 devfreq 事件设备。
参数
struct devfreq_event_dev *edev
devfreq-event 设备
描述
请注意,此函数会移除已注册的 devfreq 事件设备。
-
struct devfreq_event_dev *devm_devfreq_event_add_edev(struct device *dev, struct devfreq_event_desc *desc)¶
资源管理的
devfreq_event_add_edev()
参数
struct device *dev
拥有要创建的 devfreq 事件设备的设备
struct devfreq_event_desc *desc
devfreq 事件设备的描述符,其中包含 devfreq 事件设备的基本数据。
描述
请注意,此函数使用设备资源管理自动管理 devfreq 事件设备的内存,并简化 devfreq 事件设备内存的释放操作。
-
void devm_devfreq_event_remove_edev(struct device *dev, struct devfreq_event_dev *edev)¶
参数
struct device *dev
拥有要创建的 devfreq 事件设备的设备
struct devfreq_event_dev *edev
devfreq-event 设备
描述
请注意,此函数使用设备资源管理自动管理 devfreq 事件设备的内存。