Linux pinctrl子系統分析之六 設備與pinctrl子系統的bind

     本章我們分析設備與pinctrl子系統的bind,在前面幾章我們介紹了soc pin 描述相關的數據結構與註冊接口、board pin 描述相關的數據結構與註冊接口,但是我們卻沒有看到是在何時由誰實現對設備相關的引腳進行引腳複用與引腳配置的,而這些就是本章的內容。

 

 

設備與pinctrl 子系統的bind

     在前面我們說了,device是pinctrl的持有者,因此設備相關的引腳複用設置以及引腳配置均應由設備來進行控制,若由設備進行控制的話,難道由每個設備的驅動程序實現引腳複用相關的調用,那豈不是很大的改動量???在進行開發設計時,這種方式顯然是不可取的,在pinctrl子系統的實現中,藉助設備驅動模型中的driver_probe_device接口,當device與drivermatch後,在driver_probe_device->really_probe的接口中,在調用driver/bus的probe接口進行probe之前,通過調用pinctrl_bind_pins接口實現dev與pinctrl子系統的綁定,並完成pin相關的複用與配置操作。那爲什麼是在調用driver/bus的probe接口進行probe之前??因爲driver的probe接口中會訪問設備,因此需要在訪問設備操作之前,完成引腳的配置。

 

pinctrl_bind_pins接口

      那pinctrl_bind_pins接口實現什麼功能呢?我們通過之前分析數據結構、pinctrl device、pinctrl map,大概也可知道一二,主要包含如下內容:

  1. 完成如下的數據結構關聯圖,爲該設備申請struct dev_pin_info類型的內存空間;
  2. 根據設備名稱,在pinctrl_list鏈表查找該設備對應struct pinctrl 類型的變量:
    1. 若pinctrl_list鏈表上存在對應的pinctrl,則將其與struct dev_pin_info進行綁定;
    2. 若pinctrl_list鏈表上不存在對應的pinctrl,則首先調用pinctrl_dt_to_map接口,對於支持設備樹的內核,則解析該設備的節點內容,解析出該設備所對應的map信息,並pinctrl map註冊至pinctrl_maps鏈表上;然後則申請struct pinctrl類型的內存空間,並查找pinctrl_maps鏈表上所有dev_name與該設備名稱相同的pinctrl_map,並依據pinctrl_map信息爲該pinctrl創建對應的state,併爲該state創建對應的pinctrl_setting信息,至此即完成下圖中數據結構間的關聯圖(其中pinctrl_setting中存儲了該device對應的mux group、pin/group config相關的group/pin id、function id等信息)。
  3. 獲取該dev default state或者init state對應的struct pinctrl_state類型的變量,然後調用接口pinctrl_select_state進行group mux、group/pin config的操作,即完成設備相關引腳的配置。

 

 

而pinctrl_bind_pins接口也基本上就是實現上述內容,下面是該函數的實現代碼,其中

  1. devm_pinctrl_get則實現上述1-2中描述的內容;
  2. 而通過pinctrl_lookup_state完成該設備init_state、default_state、sleep_state、idle_state的查找,最後調用pinctrl_select_state接口,實現引腳複用以及引腳配置操作(針對group mux,則最終調用pinctrl_dev提供的pin_request、set_mux實現相應的引腳複用設置操作;針對pin/group config,則最終調用pinctrl_dev提供的pin_config_group_set實現pin/group的配置,有興趣的童鞋可以跟蹤一下,這部分的代碼不復雜)。

 

 

 

 

devm_pinctrl_get接口

    剛纔上面說了,該接口實現pinctrl的查找或創建工作,下面我們說明一下,其內部主要調用pinctrl_get實現pinctrl的查找或創建工作。

     pinctrl_get的實現簡單明瞭:

  1. 調用find_pinctrl接口,根據設備名稱從pinctrl_list中查找是否存在該pinctrl,若存在函數返回;
  2. 若未找到,則調用create_pinctrl創建一個pinctrl。

 

 

create_pinctrl

如下即是create_pinctrl接口的實現,其主要內容:

  1. 調用pinctrl_dt_to_map接口,針對支持設備樹的情況,則對該設備的節點內容進行解析,解析出該設備對應的pinctrl map信息,並註冊至pinctrl_maps鏈表中,一個設備對應的pinctrl map包括mux group、pin/group config等(可參考上一篇文章內容)。pinctrl_dt_to_map主要調用pinctrl dev的dt_node_to_map接口對設備節點中的map信息進行解析;
  2. 在pinctrl_maps鏈表上,查找該設備所對應的所有pinctrl_map(根據設備名稱查找),然後根據pinctrl_map提供的信息,調用add_setting,爲該pinctrl創建pinctrl_state、並設置pinctrl_state對應的pinctrl_setting信息,就是實現最上面的數據結構間的關聯,大家對照着上面的數據結構再去看add_setting接口的實現就相對容易很多。

 

 

 

以上即是設備與pinctrl綁定的大致分析,希望對大家有所幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章