linux pinctl 分析,基于Linux 3.10.49内核的pinctrl流程分析

本文详细介绍了 Linux 内核 3.10.49 版本中 pinctrl (Pin Controller) 的核心结构体及关键函数,包括 struct pinctrl_desc 和 struct pinctrl_dev 的组成要素,以及如何利用这些结构体进行设备引脚配置。
摘要由CSDN通过智能技术生成

linux kernel 3.10.49+

重要结构体:

struct pinctrl_desc {                      // pinctrl_register(...) 使用到.

const char *name;                      // 设备的名字platform_device传过来, 注意:不是node(dts 节点)的名字, 是xxxxx.*或a8000000.xxxxx

struct pinctrl_pin_desc const *pins;    // 引脚枚举{枚举号, 引脚名字}  // 全局变量赋值  ---|

unsigned int npins;                    // 引脚总数                    //              ---| 这两个pinctrl_register_pins会使用到.

const struct pinctrl_ops *pctlops;      // 必须                        // 全局变量赋值

const struct pinmux_ops *pmxops;        // 可选(引脚复用时,需选上)      // 全局变量赋值

const struct pinconf_ops *confops;      // 可选(一般不用.)              // 全局变量赋值

struct module *owner;                  // THIS_MODULE

};

struct pinctrl_dev      : pinctrl设备结构体(包含struct device通用属性, 其它是pinctrl独有属性)

struct platform_device  : platform设备结构体(包含struct device通用属性, 其它是pinctrl独有属性)

// 用of 解析的dts设备, 一开始都认为是platform设备, 所以都使用platform_driver_register来注册, probe回传platform_device结构体

// 如: gpio, pinctrl

// pinctrl 会通过pinctrl_register把转platform_device换成pinctrl_dev. (通用属性, 直接赋值过来, 其它重新初始化.)

重要变量:

pinctrl_maps: 这个是全局变量, 虽然与struct pinctrl_maps同名, 由LIST_HEAD(pinctrl_maps)生成

// 在drivers/pinctrl/core.c路径下.由pinctrl_register_map(...)函数使用.

// 保存引脚控制句柄(struct pinctrl_dt_map)列表, 每个设备(dts带有pinctrl-0和pinctrl-names两个属性)驱动注册时, 都会过来全部保存.

// 如果节点有pinctrl-0和pinctrl-names两个属性, 则说明这个节点有复用信息,

// 所以这个节点驱动注册时去轮询dts时, 保存这个节点的子节点的io复用的group, function两个字符串信息.

//

// struct pinctrl_map 包含于struct pinctrl_maps, 是专门保存group, function两个字符串信息的容器.

//

// 如果dts中有两个节点带有pinctrl-0, 则pinctrl_maps列表中就会有两个有效struct pinctrl_dt_map的数据.

// 简单地说, 就复用信息映射

pinctrl_list: 这个是全局变量, 由static LIST_HEAD(pinctrl_list)生成

// 在drivers/pinctrl/core.c路径下.由create_pinctrl(...)函数使用.

// 保存引脚控制句柄(struct pinctrl)列表, 每个设备驱动注册时, 都会过来保存一次.

// struct pinctrl有两个比较重要的成员states, dt_maps;

// dt_maps如果节点dts带有pinctrl-0(也就是说是dts描述复用的设备), 那么dt_maps与struct pinctrl_dt_map一样, 否则为空.

// states如果节点dts带有pinctrl-0(也就是说是dts描述复用的设备), 那么states与pinctrl-names的值一样, 一般来说只有一个"default"值, 否则为空(如:gpio为空)

##########################################################################################################################################

重要函数:

static inline void platform_set_drvdata(struct platform_device *pdev, void *data);

// 设置platform_device的私有数据(自定义数据), 实际上是保存私有指针到pdev->dev->p->driver_data

// pdev->dev                        :是struct device通用属性

// pdev->dev->p                    :是struct device 的 struct device_private 结构体指针

// pdev->dev->p->driver_data        :可以存放自定义数据的指针

static inline void *platform_get_drvdata(const struct platform_device *pdev);

// 获取platform_device的私有数据(自定义数据的指针)

static inline const char *dev_name(const struct device *dev)

// 获取struct device的name, 因为struct device没有name成员, 可以用这个.

static struct pinctrl_state *create_state(struct pinctrl *p,

const char *name);

// 参数:

// p: 就是引脚控制句柄,

// name: pinctrl-names的值, 或PINCTRL_STATE_DEFAULT

static struct pinctrl_state *find_state(struct pinctrl *p,

const char *name);

// 参数:

// p: 就是引脚控制句柄,

// name: pinctrl-names的值, 或PINCTRL_STATE_DEFAULT, 一般为PINCTRL_STATE_DEFAULT

struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p,

const char *name);

// 参数:

// p: 就是引脚控制句柄,

// name: pinctrl-names的值, 或PINCTRL_STATE_DEFAULT, 一般为PINCTRL_STATE_DEFAULT

##########################################################################################################################################

其它, 重要函数:

struct list_head;  // 只是一个环形链表指针管理工具, 构建结构体包含它, 就可以通过container_of宏访问到构建的结构体变量.

static inline void list_add(struct list_head *new, struct list_head *head);

// 环形链表, 把 new 插入到 head 的后面

// 如 head == h 10 20

// 如 1 --> head == h 1 10 20

// 如 2 --> head == h 2 1 10 20

static inline void list_add_tail(struct list_head *new, struct list_head *head)

// 环形链表, 把 new 插入到 head 的前面

// 如 head == h 10 20

// 如 1 --> head == 1 h 10 20      ==> [ h 10 20 1 ]

// 如 2 --> head == 2 h 10 20 1    ==> [ h 10 20 1 2 ]

重要宏:

LIST_HEAD(name)

// 宏: 生成以name为名字的全局list_head变量, 并初始化成员next, prev指向自已

static inline void INIT_LIST_HEAD(struct list_head *list)

// 初始化已经存在的list变量的成员next, prev指向自已

for_each_maps(maps_node, i, map)

// 参数定义如下:

// struct pinctrl_maps *maps_node    // 只是提供struct pinctrl_maps这样一个结构体, 由typeof使用.(宏内部使用)

// int i;                            // 作为一个interator使用.(宏内部使用)

// struct pinctrl_map const *map;    // 轮询pinctrl_maps这个全局变量列表, 得到每个列表结节的成员(struct pinctrl_map).

0b1331709591d260c1c78e86d0c51c18.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值