问题
I have two device tree nodes, one sets a gpio pin and the other one configures one i2c bus, ex:
&gpio2 {
en-gpio {
gpio-hog;
gpios = <5 0>;
output-high;
};
};
&i2c1 {
gpiom1: gpio@27 {
compatible = "microchip,mcp23008";
gpio-controller;
#gpio-cells = <2>;
reg = <0x27>;
};
};
How can i add a dependency between the i2c node and gpio one? What i want to achieve is that the gpio pin should be set before the devices on i2c are initialized.
回答1:
Short answer
You can't provide dependency between nodes in this case. But most likely the correct order is already taken care of in your case, and GPIO pin will be set before I2C device initialization, thanks to earlier initcall used for GPIO controller driver, and because gpio-hog
is used. If you want to check it for your platform to be sure -- below are details.
Nodes relationship
As stated in Device trees II: The harder parts LWN article:
Naturally, in each case the device which provides the interrupt or GPIO will need to be initialized before it can be found and used. It wasn't very many kernel versions ago that this was a real problem. However in the 3.4 kernel, drivers gained the ability for their initialization (or
probe
) routine to return the errorEPROBE_DEFER
which would cause the initialization to be tried again later. So if a driver finds that a GPIO line is listed in the devicetree, but no driver has registered GPIOs for the target node yet, it can fail withEPROBE_DEFER
and know it can try again later. This can even be used to remove the need for callbacks and delayed registration in board files, but it is really essential for devicetree, and happily it works quite well.
Alas, in your case it's probably not possible to specify dependency between nodes, so that your i2c1
or gpiom1
depends on gpio2
. At least I don't see any gpios
properties for I2C controllers or GPIO controllers in Documentation/devicetree/bindings/
, that can be used for referencing your en-gpio
. So it seems like you should rely on drivers loading order.
Driver dependencies
There are two possible dependencies between drivers:
- If drivers are built-in (inside of kernel image): drivers can be initialized at different initcalls, thus being loaded in correct order
- If drivers are loadable (
.ko
files): drivers can have dependencies, defined in kernel build system
As you didn't mention your platform, let's see how it works using BeagleBone Black board for example. You can use this as a template to find out how it's done on your platform.
Static dependencies
Let's check drivers init order:
- From
am33xx-l4.dtsi
file we can see that:- GPIO controller:
compatible = "ti,omap4-gpio"
- I2C controller:
compatible = "ti,omap4-i2c"
- I2C device:
compatible = "microchip,mcp23008"
- GPIO controller:
- Corresponding drivers for those compatible strings are:
- GPIO controller:
drivers/gpio/gpio-omap.c
- I2C controller:
drivers/i2c/busses/i2c-omap.c
- I2C device:
drivers/pinctrl/pinctrl-mcp23s08.c
- GPIO controller:
- Those drivers are initialized on next initcalls:
- GPIO controller:
postcore_initcall
(=2) - I2C controller:
subsys_initcall
(=4) - I2C device:
subsys_initcall
(=4)
- GPIO controller:
So GPIO controller driver will be initialized before I2C drivers.
Dynamic dependencies
What about dynamic dependencies? From corresponding Makefile
and Kconfig
files we can see config options and dependencies:
- GPIO controller:
CONFIG_GPIO_OMAP
, tristate, doesn't depend on I2C stuff - I2C controller:
CONFIG_I2C_OMA
, tristate, doesn't depend on GPIO stuff - I2C device:
CONFIG_PINCTRL_MCP23S08
, tristate, depends on I2C
So if drivers are loaded in user-space as .ko
files, it all depends on the order of their loading, user must take care of it in rootfs. Usually GPIO and I2C controller drivers are built-in, so no need to discuss this further, but just FYI, here is how the order is defined for modprobe
tool.
Kernel Configuration
To check how drivers are built (built-in or loadable), one can check .config
file. E.g. if multi_v7_defconfig
is used:
CONFIG_GPIO_OMAP=y
CONFIG_I2C_OMAP=y
In that case both drivers are built-in, and we know that GPIO driver has earlier initcall than I2C one.
GPIO hogging
You did the right thing by declaring your pin as gpio-hog
. You probably already know what it means, but I'll reference the explanation here for everyone else who is interested. From Documentation/devicetree/bindings/gpio/gpio.txt:
The GPIO chip may contain GPIO hog definitions. GPIO hogging is a mechanism providing automatic GPIO request and configuration as part of the gpio-controller's driver probe function.
So this is as early as you can get. And if your GPIO controller driver is built-in and has initcall number smaller than one for I2C drivers, you can argue that your en-gpio
pin will be set before I2C device driver init.
来源:https://stackoverflow.com/questions/57202134/device-tree-dependency-between-two-nodes