針對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)。