Linux内核中pca953x驱动platform_data的irq_base值来源疑问
我正在分析TI TCA6408设备对应的gpio-pca953x驱动,其probe()函数中有一段从设备获取platform_data的代码:
static int pca953x_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { [...] int irq_base = 0; struct pca953x_platform_data *pdata; pdata = dev_get_platdata(&client->dev); irq_base = pdata->irq_base; [...] }
该结构体定义如下:
struct pca953x_platform_data { /* number of the first GPIO */ unsigned gpio_base; /* initial polarity inversion setting */ u32 invert; /* interrupt base */ int irq_base; void *context; /* param to setup/teardown */ int (*setup)(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context); int (*teardown)(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context); const char *const *names; };
我的疑问是:驱动内找不到对pca953x_platform_data任何字段的赋值操作,那这个结构体的irq_base字段的值是怎么被设置的?调用dev_get_platdata()仅返回dev->platform_data中存储的内容,我完全搞不懂。
附示例设备树:
#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> i2c0 { #address-cells = <1>; #size-cells = <0>; gpio@20 { compatible = "nxp,pca9505"; reg = <0x20>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pca9505>; gpio-controller; #gpio-cells = <2>; interrupt-parent = <&gpio3>; interrupts = <23 IRQ_TYPE_LEVEL_LOW>; usb3-sata-sel-hog { gpio-hog; gpios = <4 GPIO_ACTIVE_HIGH>; output-low; line-name = "usb3_sata_sel"; }; }; };
我推测有代码会为pca953x_platform_data结构体分配内存并赋值,但在该驱动里找不到相关逻辑。
首先明确:pca953x_platform_data的初始化根本不在gpio-pca953x驱动内部,它属于Linux内核里的「传统平台数据」机制,赋值逻辑分两种场景:
1. 非设备树(老内核/传统BSP)场景
在板级支持包(BSP)的板文件(比如board-xxx.c这类文件)里,会预先完成以下操作:
- 分配
pca953x_platform_data结构体的内存 - 手动初始化
irq_base、gpio_base等需要的字段 - 将这个结构体的指针赋值给
i2c_board_info结构体的platform_data字段 - 通过
i2c_register_board_info()接口注册该I2C设备
当I2C核心层匹配到gpio-pca953x驱动后,会把预初始化好的平台数据关联到i2c_client->dev.platform_data,所以驱动里调用dev_get_platdata()就能直接拿到已经设好值的结构体。
2. 设备树(现代内核)场景
你贴的驱动代码里直接读取platform_data的逻辑,其实是兼容老版本的遗留代码。现代内核中,gpio-pca953x驱动已经支持设备树解析,会通过of_match_table匹配设备树节点,然后从节点属性提取配置,或者由内核动态分配资源:
- 如果设备树节点里有
gpio-base属性,会直接用这个值初始化gpio_base;如果没有,内核会自动分配可用的GPIO基地址 - 对于
irq_base,现在内核更倾向于动态分配,驱动会通过gpiochip_add_data()这类接口向GPIO子系统注册芯片,由内核统一管理中断编号,不需要手动指定irq_base(你代码里初始化为0,后续大概率会被内核分配的实际值覆盖)
你提供的示例设备树里没有irq-base或gpio-base属性,说明系统依赖内核动态分配资源,所以你在驱动里找不到赋值逻辑——这部分逻辑在内核的GPIO子系统或者设备树核心层,不在具体的芯片驱动代码里。
总结:platform_data的初始化是板级代码或内核核心层的工作,芯片驱动只负责使用这些预配置好的数据,所以你在gpio-pca953x驱动里找不到赋值逻辑是完全正常的。
内容的提问来源于stack exchange,提问作者bielu000

