You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核中pca953x驱动platform_data的irq_base值来源疑问

问题:gpio-pca953x驱动中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 14:05:54