Linux pinctrl子系統分析之四 pinctrl device的註冊與註銷

2020-08-29 jerry的編程路

前面我們分析了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 註冊與註銷實現的功能

其實pinctrl device的註冊就是實現如下圖的數據結構間的關聯,這個我們之前也說了,理清了數據結構間的關係,也就知道相應函數的實現流程了,尤其是linux內核的代碼,只要理解數據結構間的關係,那理解一個驅動模塊就事半功倍了。

pinctrl_register接口

針對pinctrl_register接口就是建立下圖的數據結構間的關聯圖,下面我們具體說明:

  1. 調用pinctrl_register進行pinctrl device的註冊時,需要傳遞struct pinctrl_desc類型的變量,該變量用於描述一個soc pin controller的信息,包含所支持的pin引腳的描述(每一個引腳的名稱與index)、pin復用操作的接口(主要是struct pinmux_ops類型的變量,包含引腳的申請與釋放接口、引腳復用設置接口、gpio引腳復用配置以及方向設置接口等)、pin引腳或group相關的引腳配置接口(包含引腳配置接口、引腳當前配置參數獲取接口、group相關引腳的配置接口、debug接口等)、group相關的操作接口(獲取group的個數、獲取group的名稱、獲取group對應的引腳內容、從設備樹設備節點中解析board pin描述信息並進行pinctrl map註冊的接口dt_node_to_map)
  2. 根據struct pinctrl_desc類型變量中的引腳描述成員pins、npins,對pin引腳進行解析,並針對每一個pin均創建一個對應的struct pin_desc類型的變量,並將其加入到基數樹pinctrl_dev->pin_desc_tree中,而struct pin_desc則主要描述該pin當前的配置信息(所屬function、group、pin引腳配置計數等,該數據結構在上一章已經介紹,當我們進行引腳復用配置調用pin_request時,則根據struct pin_desc類型變量記錄的值確定該引腳是否已經被別的模塊配置);
  3. 需要檢查pinctrl_desc定義的pinmux_ops、pinctrl_ops、pinconf_ops變量中各接口是否定義,做合法性檢測;
  4. 當完成以上操作後,即將該struct pinctrl_dev類型的變量添加到pinctrldev_list鍊表上,至此完成pinctrl device的註冊。

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_unregister接口

該接口實現的功能剛好和pinctrl_register相反,此處就不細述。

Pinctrl device driver的實現流程

下面我們描述下如何實現pinctrl device driver,主要包含如下幾個步驟:

  1. 為該soc pin controller 實現platform device driver驅動,然後在該驅動的probe接口中實現如下功能:
    1. 定義struct pinctrl_desc類型的變量,並實現相應的成員變量的配置,包含支持的引腳描述、支持的引腳復用接口的賦值、支持的引腳配置接口的賦值、支持的group操作接口以及dt2map接口的賦值等;
    2. 調用pinctrl_register/devm_pinctrl_register完成pinctrl device的註冊
    3. 定義該soc pin controller的group相關變量的添加(若使用自行定義的結構存儲就自行實現,也可調用pinctrl_generic_add_group接口實現);
    4. 定義該soc pin controller的function相關變量的添加(若使用自行定義的結構存儲就自行實現,也可調用pinctrl_generic_add_function接口實現);

完成以上幾步,基本上就完成了pinctrl device driver的註冊。在本專欄的最後,我將實現一個虛擬的pinctrl device driver,並藉助sysfs進行調試,從而完成pinctrl 子系統的驅動開發實踐。

相關焦點

  • Linux pinctrl子系統分析之五 pinctrl map註冊與註銷
    前面我們分析了pinctrl device的註冊與註銷接口。本章我們分析pinctrl maps的註冊,pinctrl maps屬於board pin描述相關的範疇。 針對pinctrl map的註冊與註銷主要涉及兩方面:當內核不支持設備樹時,則通過調用pinctrl_register_mappings、pinctrl_register_map接口實現pinctrl maps的註冊;當內核支持設備樹時,則在設備與驅動match後,在設備驅動的probe接口調用pinctrl_bind_pins
  • 輕鬆掌握pinctrl子系統驅動開發——一個虛擬pinctrl dev驅動開發
    這周主要對pinctrl子系統進行分析,該分析的基本上已經分析完成,唯一沒有細說的估計就是gpio與pinctrl之間的關聯了。本章即是pinctrl子系統分析的最後一章,本章我們主要實現一個虛擬的pinctrl device驅動,以便我們能夠使用pinctrl子系統提供的接口,實現pinctrl device的驅動開發(本章實現的驅動代碼可以在ubuntu18.04系統上正常運行)。
  • Linux pinctrl子系統分析之六 設備與pinctrl子系統的bind
    本章我們分析設備與pinctrl子系統的bind,在前面幾章我們介紹了soc pin 描述相關的數據結構與註冊接口、board pin 描述相關的數據結構與註冊接口,但是我們卻沒有看到是在何時由誰實現對設備相關的引腳進行引腳復用與引腳配置的,而這些就是本章的內容。
  • Linux regulator子系統分析之三 regulator註冊、註銷接口分析
    在上一章我們介紹了regulator子系統相關的數據結構間的關聯以及每一個數據結構的定義。針對數據結構間的關聯則需要regulator子系統提供的接口實現。而本章我們就說明這些接口。本章的章節如下:一、regulator device的註冊與註銷二、regulator的註冊與註銷(regulator device的使用者)三、regulator子系統提供的接口一、regulator device的註冊與註銷針對regulator device的註冊與註銷函數主要涉及regulator_register、regulator_unregister
  • Pinctrl子系統重要概念
    所以,要把引腳的復用、配置抽出來,做成Pinctrl子系統,給GPIO、I2C等模塊使用。BSP工程師要做什麼?看下圖:等BSP工程師在GPIO子系統、Pinctrl子系統中把自家晶片的支持加進去後,我們就可以非常方便地使用這些引腳了
  • 「正點原子Linux連載」第四十五章 pinctrl和gpio子系統實驗一
    45.1 pinctrl子系統45.1.1 pinctrl子系統簡介Linux驅動講究驅動分離與分層,pinctrl和gpio子系統就是驅動分離與分層思想下的產物,驅動分離與分層其實就是按照面向對象編程的設計思想而設計的設備驅動框架,關於驅動的分離與分層我們後面會講。
  • Linux下如何使用X86 CPU的GPIO
    2.linux pinctrl子系統要使用gpio需要先看一下linux系統PINCTRL子系統,層級如下所示(圖片來源蝸窩科技):關於linux GPIO與pinctrl子系統信息,詳見 蝸窩科技-GPIO子系統 .
  • Linux regmap子系統分析之二 從數據結構分析系統實現
    上一章我們簡要分析了regmap子系統,本章我們將從regmap子系統的數據結構介紹regmap子系統的實現。 一、數據結構間的關聯及說明 針對regmap子系統,我們首先要知道regmap子系統要解決的痛點是什麼?
  • 「正點原子Linux連載」第六十二章Linux SPI驅動實驗
    如果使用spi_bitbang_start註冊spi_master的話就要使用spi_bitbang_stop來註銷掉spi_master。62.3 SPI設備驅動編寫流程62.3.1 SPI設備信息描述1、IO的pinctrl子節點創建與修改首先肯定是根據所使用的IO來創建或修改pinctrl子節點,這個沒什麼好說的,唯獨要注意的就是檢查相應的IO有沒有被其他的設備所使用
  • LINUX IIO子系統專欄分析之一 IIO子系統概述
    從本章開始,我們進行IIO子系統專欄的分析文檔,本次IIO子系統專欄分析文檔大概包含如下幾章:一、 IIO子系統概述二、IIO子系統相關數據結構分析三、iio trigger 介紹四、iio event介紹五、iio buffer介紹六、iio device的註冊與註銷介紹七、iio trigger
  • 「正點原子Linux連載」第五十九章Linux LCD驅動實驗
    換言之就是,LCD的驅動就是構建fb_info,並且向系統註冊fb_info的過程。④、使用register_framebuffer函數向Linux內核註冊初始化好的fb_info。第30~36行,子節點pinctrl_lcdif_ctrl,RGB LCD的4根控制線配置項,包括CLK、ENABLE、VSYNC和HSYNC。第37~40行,子節點pinctrl_pwm1,LCD背光PWM引腳配置項。
  • Linux regulator子系統分析之四 虛擬regulator device驅動實現
    在前面幾章,我們分析了regulator子系統框架,主要是從數據結構及數據結構間的關聯分析了regulator子系統。為了讓大家對regulator子系統有一個深入的認識,我們本章將實現一個虛擬的regulator device驅動,從而掌握對regulator子系統的開發流程。
  • 「正點原子Linux連載」第六十一章Linux I2C驅動實驗
    註銷I2C設備驅動的時候需要將前面註冊的i2c_driver從Linux內核中註銷掉,需要用到i2c_del_driver函數,此函數原型如下:void i2c_del_driver(struct i2c_driver *driver)函數參數和返回值含義如下:
  • GPIO和Pinctrl子系統的使用在100ASK_IMX6ULL上機實驗
    GIT去了,使用GIT命令載後,在這個目錄下:01_all_series_quickstart\04_快速入門_正式開始\02_嵌入式Linux驅動開發基礎知識\source\05_gpio_and_pinctrl
  • Linux input子系統編程、分析與模板
    對象  void input_free_device(struct input_dev *dev);  初始化 初始化一個input對象是使用input子系統編寫驅動的主要工作,內核在頭文件"include/uapi/linux/input.h"中規定了一些常見輸入設備的常見的輸入事件,這些宏和數組就是我們初始化input對象的工具。
  • 「正點原子Linux連載」第五十八章Linux INPUT子系統實驗
    本章我們就來學習一下Linux內核中的input子系統。58.1 input子系統58.1.1input子系統簡介input就是輸入的意思,因此input子系統就是管理輸入的子系統,和pinctrl和gpio子系統一樣,都是Linux內核針對某一類設備而創建的框架。
  • Linux regulator子系統分析之一 總體概述
    Linux regulator 子系統主要用於管理電壓、電流電源設備的電壓、電流輸入使能、動態調整電壓、電流等,屬於電源管理的一部分。從本章開始我們分析regulator子系統。主要分為如下幾部分:一、regulator子系統總體概述二、regulator相關數據結構分析三、regulator相關註冊、註銷函數分析四、regulator設備驅動實現本章主要對regulator子系統進行簡要說明。
  • 「正點原子Linux連載」第三十七章Linux內核移植
    使用FileZilla將其發送到Ubuntu中並解壓,得到名為linux-imx-rel_imx_4.1.15_2.1.0_ga的目錄,為了和NXP官方的名字區分,可以使用「mv」命令對其重命名,我這裡將其重命名為「linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek」,命令如下:mv linux-imx-rel_imx_4.1.15