1.内核对设备树的处理
从源代码文件 dts 文件开始,设备树的处理过程为:
① dts 在 PC 机上被编译为 dtb 文件;
② u-boot 把 dtb 文件传给内核;
③ 内核解析 dtb 文件,把每一个节点都转换为 device_node 结构体;
④ 对于某些 device_node 结构体,会被转换为 platform_device 结构体。
2.dtb 中每一个节点都被转换为 device_node 结构体
根节点被保存在全局变量 of_root 中, 从 of_root 开始可以访问到任意节点。
3.哪些设备树节点会被转换为 platform_device
3.1 根节点下含有 compatile 属性的子节点 。
3.2 含有特定 compatile 属性的节点的子节点。
如果一个节点的 compatile 属性,它的值是这 4 者之一: "simple-bus","simple-mfd","isa","arm,amba-bus", 那么它的子结点(需含 compatile 属性)也可以转换为 platform_device。
3.3 总线 I2C、 SPI 节点下的子节点: 不转换为 platform_device 。
某个总线下到子节点, 应该交给对应的总线驱动程序来处理, 它们不应该被转换为platform_device。
比如以下的节点中:
/mytest 会被转换为 platform_device, 因为它兼容"simple-bus";它的子节点/mytest/mytest@0 也会被转换为 platform_device。/i2c 节点一般表示 i2c 控制器, 它会被转换为 platform_device, 在内核中有对应的 platform_driver;
/i2c/at24c02 节点不会被转换为 platform_device, 它被如何处理完全由父节点的platform_driver 决定, 一般是被创建为一个 i2c_client。
类似的也有/spi 节点, 它一般也是用来表示 SPI 控制器, 它会被转换为 platform_device,在内核中有对应的 platform_driver;
/spi/flash@0 节点不会被转换为 platform_device, 它被如何处理完全由父节点的platform_driver 决定, 一般是被创建为一个 spi_device。
/ { mytest { compatile = "mytest", "simple-bus"; mytest@0 { compatile = "mytest_0"; }; }; i2c { compatile = "samsung,i2c"; at24c02 { compatile = "at24c02"; }; }; spi { compatile = "samsung,spi"; flash@0 { compatible = "winbond,w25q32dw"; spi-max-frequency = <25000000>; reg = <0>; }; }; };
4.怎么转换为 platform_device
platform_device 中含有 resource 数组, 它来自 device_node 的 reg, interrupts 属性。
platform_device.dev.of_node 指向 device_node, 可以通过它获得其他属性。
5.platform_device 如何与 platform_driver 配对
从设备树转换得来的 platform_device 会被注册进内核里,以后当我们每注册一个platform_driver 时, 它们就会两两确定能否配对,如果能配对成功就调用 platform_driver 的
probe 函数。
其中1.3.4在之前的随笔中已经讨论过了。这边直接讨论2中用设备树匹配。
比较: platform_device. dev.of_node 和 platform_driver.driver.of_match_table。
由设备树节点转换得来的 platform_device 中,含有一个结构体: of_node。
它的类型如下:
如果一个 platform_driver 支持设备树,它的 platform_driver.driver.of_match_table 是一个数组,类型如下:
使用设备树信息来判断 dev 和 drv 是否配对时,
首先,如果 of_match_table 中含有 compatible 值,就跟 dev 的 compatile 属性比较,若一致则成功,否则返回失败;
其次,如果 of_match_table 中含有 type 值,就跟 dev 的 device_type 属性比较,若一致则成功,否则返回失败;
最后,如果 of_match_table 中含有 name 值,就跟 dev 的 name 属性比较,若一致则成功,否则返回失败。
而设备树中建议不再使用 devcie_type 和 name 属性,所以基本上只使用设备节点的compatible 属性来寻找匹配的 platform_driver。