Linux kernel 驱动中,有不少驱动会引用到 EPROBE_DEFER 这个错误号。比如下面这个例子,对 devm_gpiod_get 的返回值进行判断,如果有错误且错误号不是 -EPRBOE_DEFER,才输出error log。
那么 EPRBOE_DEFER 有什么特别之处吗,需要驱动程序这样特意处理?这个与 kernel 设计的 driver-deferred-probe 机制有关。
kernel 下有多个独立的驱动,每个驱动或多或少地会引用到其他驱动提供的资源,比如某个外设驱动需要使用 gpio 资源,就会通过 gpio 驱动提供的函数接口去申请 gpio;但是当A驱动引用B驱动提供的资源时,B驱动可能还没有工作起来,为了解决驱动之间的这种依赖关系,kernel 设计了 driver-deferred-probe 机制:某个驱动在 probe 过程中,如果遇到依赖的资源还没有准备好,那么就返回 -EPRBOE_DEFER,kernel 检测到该驱动返回的是 -EPRBOE_DEFER,就会在过一段时间后让该驱动再次 probe。
driver-deferred-probe 流程如下图所示,有三条可能的路径:
生成新的 device 时
注册新的 driver 时
later_initcall 主动再次触发
driver-deferred-probe 机制的核心数据结构与函数是:
deferred_probe_pending_list,用来记录哪些驱动被 deferred probe,并提供函数接口 driver_deferred_probe_add。
deferred_probe_work,用来调度相应的 work func 来执行 deferred probe 动作,并提供函数接口 driver_deferred_probe_trigger。
有了 driver-deferred-probe 机制后,编写驱动程序时,除了某些驱动有严格的执行次序,需要特意去定义 initcall 等级之外,一般的驱动则无需太过关心驱动间的依赖,从而在一定程度上简化了驱动开发。
以上就是对 EPRBOE_DEFER 的简要介绍。
作者:bigfish99
博客:https://www.cnblogs.com/bigfish0506/
公众号:大鱼嵌入式