Edit online

模块架构

20 Nov 2024
Read time: 1 minute(s)

pinctrl 驱动

pinctrl 子系统对 controller 进行了软件抽象,并由 controller 所实现的操作函数集来管理各个 pin 脚的属性和复用。子系统中主要的数据结构关系如下图:


pinctrl_data_struct

其相应的软件基本框架为:


pinctrl_subsystem

pinctrl 子系统的底层驱动实现,主要分为三部分:

  • struct pinconf_ops 函数集实现,主要用来设置 pin 脚的电气参数,如上下拉,驱动能力等。

  • struct pinctrl_ops 函数集实现,主要用来实现对 DTS 的解析,获取实现某一功能所需的 pin 脚信息。

  • struct pinmux_ops 函数集实现,主要用来实现功能复用,依据获取到的 pin 脚信息,实现底层的寄存器配置等。

gpio 驱动

常见的 gpio 有外挂的 gpio 芯片以及 SOC 自身的 gpio 控制器,linux 内核将这两种 gpio 统一看作是 gpio chip 进行处理。gpio 子系统整体框架如下图:


gpio_subsystem

gpio 子系统的核心就是 gpiolib。它的主要作用是:

  1. 向下为 driver 提供注册 struct gpio_chip 的接口:gpiochip_xxx()

  2. 向上为 consumer 提供引用 gpio 的接口:gpiod_xxx()

  3. 实现字符设备的功能

  4. 注册 sysfs

作为 SOC 厂商,需要实现的驱动就是 driver 部分,所以,这部分的主要工作就是实现 chip 结构体中的函数集,并注册 controller。

irqchip 驱动

当 gpio 口接收中断时,linux 内核是将 gpio 作为一个级联到 GIC 上的二级中断控制器处理的。一个典型的拓扑结构如下图:


irq_arch

linux 内核将此时的 GPIO 控制器看作是一个中断控制器,用 chip 进行软件抽象。所以需要实现相应的 gpio 中断控制器的驱动。按照 irqchip 子系统的框架,每一个中断线对应一个 desc 结构体,该结构体包含一个 irq,是该中断线的 level 中断处理函数。该函数的主要作用是:打开或关闭相应中断号的中断,通知 CPU 中断处理完成。调用底层的中断处理函数。子系统中定义了几个不同的 level 函数,可以依据不同的中断类型和不同的中断控制器,选择不同的 level 函数。

与 chip 的驱动实现有些类似,irqchip 的驱动也主要是实现 chip 中的函数集。由于 gpio 中断控制器是一个二级中断控制器,所以驱动中需要做的工作有:

  • 实现 gpio 中断控制器的驱动,主要工作是实现 chip 中的函数集

  • 实现每个 controller 的中断线所对应的中断描述符的 irq,用于在 gpio 触发中断时查找触发中断的 gpio line