前面我們分析了pinctrl子系統相關的數據結構等內容,本章我們分析pinctrl device的註冊與註銷接口。
針對pinctrl device的註冊與註銷主要涉及pinctrl_register、pinctrl_unregister、devm_pinctrl_register、devm_pinctrl_unregister這幾個接口。而devm_pinctrl_register、devm_pinctrl_unregister這兩個接口則主要由設備驅動模型實現資源申請與釋放,即使用這兩個接口,則pinctrl device無須在driver remove時進行資源的釋放(設備資源管理也是設備驅動子系統的一個模塊,該模塊實現資源的管理,也就是針對device申請的資源均存放到device的鍊表上,當對該device 進行destroy時,一併對這些資源進行釋放)。
其實pinctrl device的註冊就是實現如下圖的數據結構間的關聯,這個我們之前也說了,理清了數據結構間的關係,也就知道相應函數的實現流程了,尤其是linux內核的代碼,只要理解數據結構間的關係,那理解一個驅動模塊就事半功倍了。
針對pinctrl_register接口就是建立下圖的數據結構間的關聯圖,下面我們具體說明:
pinctrl_register、devm_pinctrl_register主要實現soc pin controller描述相關信息的定義與註冊。該接口實現的功能也就是以上四點。
pinctrl_register函數主要分為pinctrl_init_controller、pinctrl_enable兩個函數,pinctrl_init_controller函數,主要實現上述的1-3的內容,而pinctrl_enable則實現上述4的內容,主要將該pinctrl device添加到pinctrldev_list上。
pinctrl_init_controller的實現如下所示,基本上也就實現上面的1-3點的內容,根據傳遞的struct pinctrl_desc類型的變量pctldesc,申請struct pinctrl_dev類型的內存,然後初始化pin_desc_tree、pin_group_tree、pin_function_tree(這三個基數樹變量主要存儲引腳配置的變量、group相關的變量、function相關的變量等信息,其中pin引腳加入到pin_desc_tree中的操作由pinctrl_register_pisn實現。而group、function加入到pin_group_tree、pin_function_tree這個操作是新內核加入的,因此這個加入操作沒有在pinctrl_register中,而是由具體的pinctrl device driver自行調用pinctrl_generic_add_group、pinmux_generic_add_function實現,在以後的內核升級中可能也會由pinctrl_register實現)
而接口pinctrl_register_pins則根據該pinctrl device的引腳描述,將所有的引腳註冊進pinctrl device的pin_desc_tree中。該接口的實現如下,代碼邏輯也比較清晰,就不再細述。
該接口實現的功能剛好和pinctrl_register相反,此處就不細述。
下面我們描述下如何實現pinctrl device driver,主要包含如下幾個步驟:
完成以上幾步,基本上就完成了pinctrl device driver的註冊。在本專欄的最後,我將實現一個虛擬的pinctrl device driver,並藉助sysfs進行調試,從而完成pinctrl 子系統的驅動開發實踐。