pinctrl子系統分析(二)

2021-10-21 19:20:21 字數 3711 閱讀 5875

pinctrl子系統分析(一)

pinctrl子系統分析(二)

pinctrl子系統分析(三)

pin控制器驅動的主要工作是,列舉pin控制器的資訊,如控制器有多少個引腳,支援多少個function,每個function對應幾個group,支援多少個group等,建立table儲存這些資訊,最後呼叫pin control核心提供的pinctrl_register函式將pin控制器註冊進系統。

pinctrl_register函式定義如下:

struct pinctrl_dev *

pinctrl_register

(struct pinctrl_desc *pctldesc,

struct device *dev,

void

*driver_data)

/* 初始化pinctrl_dev */

pctldev->owner = pctldesc->owner;

pctldev->desc = pctldesc;

pctldev->driver_data = driver_data;

init_radix_tree

(&pctldev->pin_desc_tree, gfp_kernel)

;init_list_head

(&pctldev->gpio_ranges)

; pctldev->dev = dev;

mutex_init

(&pctldev->mutex);.

....

./* 註冊pin */

ret =

pinctrl_register_pins

(pctldev, pctldesc->pins, pctldesc->npins);.

....

.mutex_lock

(&pinctrldev_list_mutex)

;//把pinctrl_dev插入全域性鍊錶pinctrldev_list

list_add_tail

(&pctldev->node,

&pinctrldev_list)

;mutex_unlock

(&pinctrldev_list_mutex);.

....

}

註冊pin控制器所有的pin:

static

intpinctrl_register_pins

(struct pinctrl_dev *pctldev,

struct pinctrl_pin_desc const

*pins,

unsigned num_descs)

return0;

}static

intpinctrl_register_one_pin

(struct pinctrl_dev *pctldev,

const

struct pinctrl_pin_desc *pin)

else

pindesc->drv_data = pin->drv_data;

//插入pinctrl_dev的radix tree,鍵值為pin號

radix_tree_insert

(&pctldev->pin_desc_tree, pin->number, pindesc);.

....

.}

前面提到過,裝置可能有多種狀態,不同狀態下對應的pin control state可能有所不同,而每種狀態的引腳配置由乙個或多個裝置節點來描述。

設定裝置的pin control state主要分三個步驟:

獲得裝置的pin control state holder;

呼叫pinctrl_lookup_state函式查詢裝置的pin control state;

呼叫pinctrl_select_state函式設定pin control state。

pin control state holder作為管理者,管理這裝置的pin control state,想要設定pin control state,首先得獲得holder。

呼叫pinctrl_get函式獲取裝置的pinctrl:

struct pinctrl *

pinctrl_get

(struct device *dev)

//如果在全域性鍊錶pinctrl_list上找不到的話,則為裝置建立乙個pinctrl

return

create_pinctrl

(dev)

;}

初次呼叫pinctrl_get函式,裝置是沒有pinctrl的,會自動建立,通過create_pinctrl函式:

static

struct pinctrl *

create_pinctrl

(struct device *dev)

mutex_unlock(&pinctrl_maps_mutex);*/.

....

.mutex_lock

(&pinctrl_list_mutex)

;list_add_tail

(&p->node,

&pinctrl_list)

;//把pinctrl插入全域性鍊錶pinctrl_list

mutex_unlock

(&pinctrl_list_mutex)

;return p;

}

//name指向狀態的名字

struct pinctrl_state *

pinctrl_lookup_state

(struct pinctrl *p,

const

char

*name)

else

state =

err_ptr

(-enodev);}

return state;

}static

struct pinctrl_state *

create_state

(struct pinctrl *p,

const

char

*name)

為了理清楚pinctrl與pinctrl_state的關係,我畫了下面這張圖:

pinctrl_state對應裝置一種狀態下的pin control state,其有乙個settings鍊錶,用於鏈結乙個或多個pinctrl_setting,pinctrl_setting結構體定義如下:

struct pinctrl_setting  data;

//用於配置引腳的配置資訊

};

通過pinctrl_setting,可以設定裝置在某種狀態下的引腳配置,毫無疑問,這些pinctrl_setting是通過配置節點描述的配置資訊來初始化的。

int

pinctrl_select_state

(struct pinctrl *p,

struct pinctrl_state *state)

p->state = state;

return0;

......}

pinctrl子系統分析(一)

pinctrl子系統分析 一 pinctrl子系統分析 二 pinctrl子系統分析 三 許多soc的內部都包含了pin控制器,通過pin控制器,我們可以匹配引腳的狀態和功能特性。在了解pinctrl子系統之前,我們先來了解一些基本的概念。soc的很多引腳都可以配置成不同的功能,如a1和a2兩個引腳...

pinctrl子系統分析(三)

pinctrl子系統分析 一 pinctrl子系統分析 二 pinctrl子系統分析 三 這章講解配置節點的解析以及pinctrl state的pinctrl setting增添,先來個圖 create pinctrl static struct pinctrl create pinctrl str...

framebuffer 子系統分析

fb info screen base dma alloc writecombine fbi dev,map size,map dma,gfp kernel fb info screen base 是framebuffer起始虛擬位址,也就是mmap後程式寫入fb的位址,該位址會直接寫入到fb in...