简短回答
在这种情况下,您无法提供节点之间的依赖关系。但很可能在您的情况下已经考虑了正确的顺序,并且 GPIO 引脚将在 I2C 设备初始化之前设置,这要归功于早期用于 GPIO 控制器驱动程序的 initcall,并且因为gpio-hog
用来。如果您想检查一下您的平台以确定 - 以下是详细信息。
节点关系
如中所述设备树 II:较难的部分 https://lwn.net/Articles/573409/LWN 文章:
当然,在每种情况下,提供中断或 GPIO 的设备都需要在被发现和使用之前进行初始化。在没有很多内核版本之前,这是一个真正的问题。然而,在 3.4 内核中,驱动程序获得了初始化的能力(或probe
) 返回错误的例程EPROBE_DEFER
这将导致稍后再次尝试初始化。因此,如果驱动程序发现设备树中列出了 GPIO 线,但还没有驱动程序为目标节点注册了 GPIO,则它可能会失败EPROBE_DEFER
并知道它可以稍后再试。这甚至可以用来消除对回调和板文件中延迟注册的需要,但这对于 devicetree 来说确实很重要,而且令人高兴的是它工作得很好。
唉,在您的情况下,可能无法指定节点之间的依赖关系,因此您的i2c1
or gpiom1
依赖于取决于gpio2
。至少我没有看到任何gpios
I2C 控制器或 GPIO 控制器的属性Documentation/devicetree/bindings/
,可用于参考您的en-gpio
。所以看来你应该依赖驱动程序的加载顺序。
驱动程序依赖
驱动程序之间有两种可能的依赖关系:
- 如果司机是built-in(内核映像内部):驱动程序可以在不同的位置初始化初始化调用 https://0xax.gitbooks.io/linux-insides/content/Concepts/linux-cpu-3.html,从而以正确的顺序加载
- 如果司机是loadable (
.ko
文件):驱动程序可以具有在内核构建系统中定义的依赖项
由于您没有提及您的平台,让我们看看它如何使用 BeagleBone Black board 来工作。您可以使用它作为模板来了解它在您的平台上是如何完成的。
静态依赖
让我们检查一下驱动程序的初始化顺序:
- From
am33xx-l4.dtsi
file we can see that:
- GPIO 控制器:
compatible = "ti,omap4-gpio"
- I2C控制器:
compatible = "ti,omap4-i2c"
- I2C设备:
compatible = "microchip,mcp23008"
- Corresponding drivers for those compatible strings are:
- GPIO 控制器:
drivers/gpio/gpio-omap.c
- I2C控制器:
drivers/i2c/busses/i2c-omap.c
- I2C设备:
drivers/pinctrl/pinctrl-mcp23s08.c
- Those drivers are initialized on next initcalls:
- GPIO 控制器:
postcore_initcall
(=2)
- I2C控制器:
subsys_initcall
(=4)
- I2C设备:
subsys_initcall
(=4)
因此 GPIO 控制器驱动程序将在 I2C 驱动程序之前初始化。
动态依赖
那么动态依赖呢?来自相应的Makefile
and Kconfig
文件我们可以看到配置选项和依赖项:
- GPIO 控制器:
CONFIG_GPIO_OMAP
,三态,不依赖于 I2C 的东西
- I2C控制器:
CONFIG_I2C_OMA
,三态,不依赖于 GPIO 的东西
- I2C设备:
CONFIG_PINCTRL_MCP23S08
,三态,取决于 I2C
因此,如果驱动程序加载到用户空间中.ko
文件,这完全取决于它们的加载顺序,用户必须在 rootfs 中处理它。通常GPIO和I2C控制器驱动程序是内置的,因此无需进一步讨论,仅供参考,here is https://unix.stackexchange.com/questions/90027/what-is-the-sequence-loading-linux-kernel-module-on-startup-how-priority-is-set如何定义顺序modprobe
tool.
内核配置
要检查驱动程序是如何构建的(内置的或可加载的),可以检查.config
文件。例如。如果multi_v7_defconfig
用来:
CONFIG_GPIO_OMAP=y
CONFIG_I2C_OMAP=y
在这种情况下,两个驱动程序都是内置的,并且我们知道 GPIO 驱动程序的 initcall 早于 I2C 驱动程序。
GPIO 占用
您将您的 PIN 声明为正确的做法gpio-hog
。您可能已经知道它的含义,但我会为其他感兴趣的人参考此处的解释。从文档/devicetree/bindings/gpio/gpio.txt https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt:
GPIO 芯片可能包含 GPIO hog 定义。 GPIO 占用是一种机制
提供自动 GPIO 请求和配置作为
GPIO-controller的驱动探针函数.
所以这是你能尽早得到的。如果您的 GPIO 控制器驱动程序是内置的,并且 initcall 编号小于 I2C 驱动程序的 1,那么您可以说您的en-gpio
引脚将在 I2C 设备驱动程序初始化之前设置。