除了通用属性以外,可以在一个节点中可以添加任何自定义的属性和子节点。只要遵循一些规则,可以添加任何操作系统所需要的数据。
这些定义的属性和子节点的含义必须存档在 binding 文档中(为了让其他程序员阅读,当然也可以不写,只是让别人难以理解)
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&uart2_pins_default>;
status = "okay";
rts-gpio = <&gpio1 18 GPIO_ACTIVE_HIGH>;
rx-led-gpio = <&gpio2 23 GPIO_ACTIVE_LOW>;
tx-led-gpio = <&gpio2 22 GPIO_ACTIVE_LOW>;
rs485-rts-active-high;
rs485-rts-delay = <0 0>;
linux,rs485-enabled-at-boot-time;
};
上述代码的 rx-led-gpio 、tx-led-gpio 是自定义节点
rx-led-gpio = <&gpio2 23 GPIO_ACTIVE_LOW>;
tx-led-gpio = <&gpio2 22 GPIO_ACTIVE_LOW>;
自定义节点需要在驱动里面做特殊处理
/* check for tx enable gpio */
up->rts_gpio = of_get_named_gpio_flags(np, "rts-gpio", 0, &up->flags);
if (gpio_is_valid(up->rts_gpio)) {
} else if (up->rts_gpio == -EPROBE_DEFER) {
return -EPROBE_DEFER;
} else {
up->rts_gpio = -EINVAL;
}
/* check for rx led gpio */
up->rx_led_gpio = of_get_named_gpio_flags(np, "rx-led-gpio", 0, &up->flags);
if (gpio_is_valid(up->rx_led_gpio)) {
} else if (up->rx_led_gpio == -EPROBE_DEFER) {
return -EPROBE_DEFER;
} else {
up->rx_led_gpio = -EINVAL;
}
/* check for tx led gpio */
up->tx_led_gpio = of_get_named_gpio_flags(np, "tx-led-gpio", 0, &up->flags);
if (gpio_is_valid(up->tx_led_gpio)) {
} else if (up->tx_led_gpio == -EPROBE_DEFER) {
return -EPROBE_DEFER;
} else {
up->tx_led_gpio = -EINVAL;
}
官方对自定义添加的节点要求是必须要有说明文档:
1、属性和子节点的含义必须存档在 binding 文档中,以便设备驱动程序的程序员知道如何解释这些数据。
2、一个 binding 记录了一个特定 compatible 值的意义、应该包含什么样的属性、有可能包含那些子节点、以及它代表了什么样的设备。
3、每个特别的 compatible 值都应该有一个它自己的 binding(或者要求与其他 compatible 值兼容)。新设备的 binding 存档在本 wiki 中。请查看主页上的文档格式描述和审核流程。
4、使用邮件列表 devicetree-discuss@lists.ozlabs.org 发送新的 binding 以进行审核。新 binding 的审核可以捕获很多可能在以后导致问题的常见错误。