probe()何时被调用

本文深入探讨了内核驱动注册与设备匹配的过程,详细解释了如何通过deviceid进行匹配,以及驱动如何绑定到相应的设备上。通过理解driver_register、bus_add_driver等核心函数的流程,读者可以更好地掌握Linux内核驱动的实现细节。
部署运行你感兴趣的模型镜像

1:新设备注册后,总线先match() device id, 绑定合适的驱动后,调用驱动的probe().
2:新驱动注册后,总线先match() device id,给驱动支持的, 未绑定驱动的设备绑定驱动,并把设备添加到驱动支持的设备链表尾部.然后调用probe().

--> driver_register()
  --> bus_add_driver()
    --> driver_attach()
      --> bus_for_each_dev()
        --> __driver_attach()
          --> driver_probe_device()
            --> drv->prode(dev)
                               p.s. ==> bus_for_each_dev()有4个参数, driver_attach()在调用bus_for_each_dev()的时候把__driver_attach()作为最后一个参数传给了它,
               在bus_for_each_dev()内部即:int (*fn)(struct device *, void *)这个函数.



您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<think> 我们正在讨论Linux内核中的驱动probe机制。用户之前询问了钟控制器的`recalc_rate`回调配置,现在转向了另一个驱动函数`fsl_lpspi_probe`的调用机。根据用户提供的引用内容,特别是引用[1]中关于`really_probe`函数的描述,我们可以解释probe函数的调用流程。 用户引用的内容说明了设备驱动匹配后的probe调用过程: 1. 首先,设备所属总线的probe函数被调用(如果存在)。 2. 如果总线没有probe函数,则调用驱动自己的probe函数。 因此,`fsl_lpspi_probe`作为SPI控制器的驱动probe函数,其调用机是在设备与驱动匹配之后,由内核的驱动模型通过`really_probe`函数调用的。 具体步骤: - 当内核启动或动态加载驱动,会进行设备与驱动的匹配。 - 匹配成功后(通过compatible字符串匹配),内核会调用`really_probe`函数。 - 在`really_probe`中,会依次调用总线的probe(如果有)和驱动的probe(即`fsl_lpspi_probe`)。 所以,`fsl_lpspi_probe`的调用机是:当设备树中描述的SPI控制器节点与驱动中定义的`of_device_id`表项匹配成功,在内核初始化或模块加载过程中由驱动核心调用。 此外,用户提供的引用[3]中提到了SPI传输函数,这进一步说明我们讨论的是SPI控制器驱动,其中`fsl_lpspi_probe`是NXP i.MX系列芯片的LPSPI(Low Power SPI)控制器的驱动探测函数。 总结调用机: 1. 内核启动过程中,设备与驱动匹配。 2. 动态加载驱动模块,如果设备存在且匹配。 3. 热插拔事件(如果支持)导致设备出现。 在设备树中,SPI控制器节点会有一个compatible属性,例如: ```dts lpspi0: spi@40394000 { compatible = "fsl,imx7ulp-lpspi"; reg = <0x40394000 0x1000>; interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX7ULP_CLK_DUMMY>, <&clk IMX7ULP_CLK_LPSPI0>; clock-names = "ipg", "per"; dmas = <&edma0 0 4>, <&edma0 0 3>; dma-names = "rx","tx"; status = "disabled"; }; ``` 驱动中会有对应的`of_device_id`表: ```c static const struct of_device_id fsl_lpspi_dt_ids[] = { { .compatible = "fsl,imx7ulp-lpspi", .data = &imx7ulp_lpspi_devtype, }, { /* sentinel */ } }; ``` 当两者匹配,`fsl_lpspi_probe`被调用。 相关问题: 1. 设备树中如何配置SPI控制器节点? 2. 如何编写SPI控制器驱动的probe函数? 3. 内核驱动匹配的详细流程是怎样的? </think> ### `fsl_lpspi_probe` 函数的调用机分析 `fsl_lpspi_probe` 是 NXP i.MX 系列芯片的 LPSPI(Low Power SPI)控制器驱动中的探测函数。其调用机遵循 Linux 内核标准的驱动探测机制,发生在以下关键节点: #### 1. **驱动与设备匹配阶段** 当内核检测到与驱动兼容的设备触发: - **设备树匹配**:内核解析设备树(DTS)发现匹配节点: ```dts lpspi0: spi@40394000 { compatible = "fsl,imx7ulp-lpspi"; // 匹配驱动的compatible字段 reg = <0x40394000 0x1000>; interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX7ULP_CLK_DUMMY>; status = "okay"; }; ``` - **驱动注册**:通过 `platform_driver_register()` 注册驱动: ```c static struct platform_driver fsl_lpspi_driver = { .probe = fsl_lpspi_probe, // 注册probe函数 .driver = { .name = "fsl_lpspi", .of_match_table = fsl_lpspi_dt_ids, // 包含compatible字段 }, }; module_platform_driver(fsl_lpspi_driver); ``` 当设备树的 `compatible` 与驱动的 `of_match_table` 匹配,内核安排调用 `probe`[^1]。 #### 2. **内核探测执行流程** 匹配后内核执行探测链: ```mermaid graph LR A[设备树解析] --> B[创建platform_device] B --> C{驱动注册完成?} C -->|是| D[调用really_probe] D --> E[总线probe] --> F[驱动probe] F --> G[执行fsl_lpspi_probe] ``` 1. 内核调用 `really_probe()` 初始化设备 2. 先执行总线级回调(如 SPI 总线的 `probe`) 3. **最终调用驱动注册的 `fsl_lpspi_probe`**[^1] #### 3. **具体触发场景** | 场景 | 调用机 | 触发条件 | |--------------------------|-----------------------------------|------------------------------| | 内核启动 | 初始化期间 | 设备树包含节点且 `status=okay` | | 模块动态加载 | `insmod` 或 `modprobe` 命令执行 | 设备已存在于系统中 | | 热插拔(支持热插拔系统) | 设备插入 | 支持动态设备管理的平台 | #### 4. **函数内部典型操作** `fsl_lpspi_probe` 主要完成硬件初始化: ```c static int fsl_lpspi_probe(struct platform_device *pdev) { // 1. 获取设备树资源 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); void __iomem *base = devm_ioremap_resource(&pdev->dev, res); // 2. 申请中断 irq = platform_get_irq(pdev, 0); devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, 0, dev_name(&pdev->dev), spi_controller); // 3. 初始化SPI控制器 spi_controller = spi_alloc_host(&pdev->dev, sizeof(struct fsl_lpspi_data)); spi_controller->setup = fsl_lpspi_setup; spi_controller->transfer_one = fsl_lpspi_transfer_one; // 数据传输函数[^3] // 4. 注册控制器 spi_register_controller(spi_controller); } ``` 此函数完成后,SPI 控制器即可响应数据传输请求(如调用 `transfer_one`)[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值