device_node转换为platform_device
Posted -glb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了device_node转换为platform_device相关的知识,希望对你有一定的参考价值。
以前在写驱动程序的时候,需要把驱动分为平台device和平台driver两部分。在平台device中会放入硬件所使用的资源,使用C代码来指定platform_device,当需要修改硬件资源时,比如说想去修改led的引脚时,需要重新修改C文件,重新编译内核。再后来我们使用了设备树,可以在设备树中指定硬件资源。设备树是dts文件,它会转换成dtb文件,最终给内核使用。内核会来解析dtb文件得到一系列的device_node,现在终于来到了最后一步,将device_node转换成platform_device.
在分析如何转换之前,先来看下面的两个问题。
1、哪些device_node可以转换成platform_device?
根节点也会对应一个device_node,它并不对应什么设备,也就是说不对应什么硬件,因此根节点对应的device_node应该不会转换成platform_device。
再看一下memory,它虽然是一个硬件,但是我们并不需要什么驱动程序。内存所对应的device_node应该不会转换成platform_device
再看一些chosen,它只是用来设置一些运行时的信息,它并不对应真实的硬件,它也不应该转换成platform_device.
因此,并非所有的device_node都会转换为platform_device。 只有以下的device_node会转换:
1.1 该节点必须含有compatible属性
1.2 根节点的子节点(节点必须含有compatible属性)
1.3 含有特殊compatible属性的节点的子节点(子节点必须含有compatible属性):
这些特殊的compatilbe属性为: "simple-bus","simple-mfd","isa","arm,amba-bus"
1.4 比如以下的节点,
/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>;
};
};
};
对于根目录下的第一级子节点,比如说I2c,它应该转换成platform_device,它会对应有一个platform_driver,当匹配时,driver中的probe函数就会被调用,对于I2c下面的这些子节点,比如说AT24C02应该交给probe函数来处理。如果仍然把这些子节点转成platfrom_device的话,就不太合适了。
2. device_node如何转换成platform_device
首先来看一下,platform_device结构体的定义:
struct platform_device { const char *name; int id; bool id_auto; struct device dev; u32 num_resources; struct resource *resource; //指向一个动态生成的数组,数组的大小由num_resources决定。意味着平台设备中可以有0项,或1项,或多项资源。 //这些资源来自设备树中的reg属性,如果设备树中设有reg属性,那么在对应的platform_device中就会有一项资源, //用来表示它所占用的内存空间。还可以指定一些中断属性,那么在platform_device就会表示它占据哪个中断号。 //资源的类别:I/O资源,内存资源,中断资源,这3中资源都可以在设备树中指定。这些资源会从device_node转换得到。 const struct platform_device_id *id_entry; char *driver_override; /* Driver name to force a match */ /* MFD cell pointer */ struct mfd_cell *mfd_cell; /* arch specific additions */ struct pdev_archdata archdata; };
platform_device中含有resource数组, 它来自device_node的reg, interrupts属性;
platform_device.dev.of_node指向device_node, 可以通过它获得其他属性
以上是关于device_node转换为platform_device的主要内容,如果未能解决你的问题,请参考以下文章
RK3399平台开发系列讲解(内核设备树篇)4.22设备树dtb信息转化为device_node结构
device node结构体转换成platform_device结构体
RK3399平台开发系列讲解(内核设备树篇)3.6device_node与device绑定流程