针对linux 内核各子系统学习而言,在理解了各子系统的实现背景后,再从数据结构入手,可快速理解其子系统的实现流程。因此本章我们从regulator子系统的数据结构入手,从而理解regulator子系统的实现。本章的提纲如下:
一、数据结构间的关联说明
二、各数据结构介绍
一、数据结构间的关联说明
在上一章中,我们说明针对regulator子系统,包括regulator device(电源提供者)、电源管理芯片(pmic)、电源使用者(consumer)、电源域等几个概念。而在regulator子系统的实现中,则抽象了数据结构regulator_device(表示一个regulator device)、regulator(对应一个电源使用者 consumer),然后围绕这两个数据结构,又定义了regulator_map、regulator_enable_gpio、regulator_desc、regulator_ops、regulator_constraints、regulator_config、regulator_init_data、regulator_consumer_supply等数据结构。稍后我们一一展开说明。
如下图所示,表示数据结构struct regulator_map、struct regulator、struct regulator_dev的关联图,下面我们详细说明下这张图的意义:
- 系统中所有注册的struct regulator_dev类型的变量,均会添加到链表regulator_list中,而这些操作由接口regulator_register实现。
- 在regulator_register接口中,针对一个regulator device的所有使用者,均为其创建struct regulator_map类型变量,并将其插入regulator_map_list链表上,而struct regulator_map中包含该使用者的名称(使用者对应的设备名称、使用类型、regulator_dev类型的指针指向该电源的提供者);
- 当电源的使用者(对应的device驱动)在驱动接口中调用regulator_get,申请一个电源使用信息时,则根据该设备的名称、supply名称,在regulator_map_list上查找对应struct regulator_map类型的变量,并创建struct regulator类型的变量,并将其加入到struct regulator_dev的consumer_list链表中,从而实现下图struct regulator、struct regulator_dev的关联(它们之间的关联,需要借助注册在regulator_map_list链表的regulator_map类型变量)。
- 若该regulator_dev通过gpio进行enable/disable的控制,则在调用接口regulator_register接口进行regulator_dev的注册时,则创建对应struct regulator_enable_gpio类型变量的创建,并注册到链表regulator_ena_gpio_list中。
下图的数据结构间的关联主要借助接口regulator_register、regulator_get实现。而在regulator_register接口中实现regulator_dev、regulator_map的关联时,还涉及数据结构regulator_enable_gpio、regulator_desc、regulator_ops、regulator_constraints、regulator_config、regulator_init_data、regulator_consumer_supply的关联(这在数据结构regulator_dev中说明)
二、各数据结构介绍
本章主要介绍数据结构regulator_dev、regulator_map、regulator等数据结构
regulator_dev相关数据结构说明
struct regulator_dev包含多个数据结构,因此我们将这几个数据结构间的关联进行说明。如下图所示即为regulator_dev相关的数据结构的关联图。
struct regulator_config相关数据结构
struct regulator_config相关数据结构主要用于描述regulator_dev的所有使用者信息,以及该regulator_dev的输出参数信息,具体说明如下:
- struct regulator_consumer_supply表示一个regulator_dev的使用者描述,包含使用者对应的设备名称(也可为空)、supply名称,通过这些描述信息,在调用接口regulator_register接口进行regulator_dev的注册时,则根据该数据结构描述的信息,完成上面所说的struct regulator_map类型变量的注册,以便调用regulator_get时可实现struct regulator类型变量的创建;
- 若该regulator_dev通过gpio进行enable/disable的控制,则需要对该gpio进行描述(包含gpio号、gpio使能状态、gpio状态是否为invert等),在调用接口regulator_register接口进行regulator_dev的注册时,则创建对应struct regulator_enable_gpio类型变量的创建,并注册到链表regulator_ena_gpio_list中。
- 数据结构struct regulation_constraints描述该regulator dev相关的配置信息,包括最小输出电压、最大输出电压、初始模式、是否支持suspend state(suspend to memory、suspend to disk、suspend standby状态等)
struct regulator_desc相关数据结构
主要涉及struct regulator_desc、struct regulator_ops,具体说明如下:
- struct regulator_desc描述该regulator device的类型(电压、电流、电流和电压)、中断id、支持的输出电压个数、操作类型(可改变电压等)、输出模式(fast、normal、idle、standby等);若该regulator device在注册的时候支持通过regmap进行配置(如该regulator device可通过spi、iic接口访问,则可以通过spi/iic对应的regmap接口访问该regulator device的寄存器,进行配置操作),则需要定义enable_reg、enable_mask、Apply_reg等参数的信息,以便通过regmap进行配置
以上介绍的是数据结构间关联的说明,下面对几个数据结构进行简要说明:
struct regulator_desc
该数据结构是一个regulator_dev的描述信息:
- regulator的名称;
- 若该regulator device是由别的的regulator device提供的电源(即该regulator device是另一个regulator device的使用者),则supply_name表示提供电源的regulator device名称;
- 说明该regulator device可提供的输出电压个数、支持的输出电压列表、单步电压调节值等
- 该regulator device的操作接口(struct regulator_ops,包括设置电压、设置电流、输出使能等接口)
struct regulation_constraints
该数据结构描述regulator device的约束信息,定义如下:
- 输出电压范围;
- 输出电流范围;
- 该regulator device支持的模式(fast、normal、idle、standby等);
- 该regulator device支持的操作模式,包括change volt、change current、change bypass mode等;
- 该regulator device支持的suspend 状态下的输出控制(如在suspend to disk状态下的输出控制等);
struct regulator_dev
该数据结构表示一个regulator device,定义如下;
- 该regulator device的描述信息,struct regulator_desc类型的变量,描述regulator_dev的电压输出信息、操作信息(使能去使能接口、电压设置与获取接口、电流设置与获取接口);
- 该regulator_dev所有使用者的信息(consumer_list链表上的regulator成员);
- 该regulator_dev是另一个regulator_dev的使用者,则通过supply作为使用者信息;
- 该regulator_dev是否支持通过regmap访问;
- notifier链表,用于regulator_dev状态变化的通知链;
struct regulator
该数据结构表示一个regulator device的使用者,包括是否一直使能、是否使用bypass模式(bypass模式指regulator device输入电压直接作为输出,不做限制)、电压范围、电流值、设备属性信息、该regulator对应的supply名称等。
本章主要介绍regulator 子系统的数据结构,相对来说结构体比较多,但是我们要梳理主线,其主线即是文章开头的数据结构关联图,主要抓住regulator_dev、regulator、regulator_map这几个数据结构即可。其他的数据结构主要是为了建立这三个数据结构间的关联(借助regulator_register、regulator_get)。