Device Tree dependency between two nodes

随声附和 提交于 2021-02-10 14:35:04

问题


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 error EPROBE_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 with EPROBE_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:

  1. If drivers are built-in (inside of kernel image): drivers can be initialized at different initcalls, thus being loaded in correct order
  2. 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:

  1. 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"
  2. 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
  3. Those drivers are initialized on next initcalls:
    • GPIO controller: postcore_initcall (=2)
    • I2C controller: subsys_initcall (=4)
    • I2C device: subsys_initcall (=4)

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!