当前位置:网站首页>The device node structure is converted into a platform_device structure
The device node structure is converted into a platform_device structure
2022-08-01 01:20:00 【snail taking off】
1、函数调用关系
of_platform_default_populate_init()
of_find_node_by_path() //根据路径查找device_node结构体
of_platform_default_populate() //实例化每个device_node结构体成platform_device结构体
of_platform_populate() //获取根节点的device_node结构体,遍历每个节点,都转换成platform_device结构体
of_platform_bus_create()
of_device_is_compatible() //检查节点的compatibleIs the property andamba总线匹配
of_amba_device_create() //创建amba总线的struct amba_device
of_platform_device_create_pdata() //将device_node结构体转换成platform_device结构体
of_device_allocc() //示例化platform_device结构体,将device_nodeThe attribute value in is converted toplatform_device结构体里的resource资源
of_device_add() //Register builtplatform_device结构体到platform总线
for_each_child_of_node() //遍历节点的子节点
of_platform_bus_create() //将device_node结构体转换成platform_device结构体
(1)
device_nodeStructs can be converted to more than justplatform总线的device,还可以转换成amba总线上的设备,Specific into what kind of equipment according to the node on the buscompatible属性,The default is to convert toplatform总线的devic
e;
(2)of_platform_bus_create()The function here is a recursive call,Because the data organization of the device tree is tree-like,It is very suitable for recursive way to access;
(3)Refer to the blog for the data organization of the device tree:《How is the tree structure of the device tree reflected??》;
2、of_platform_default_populate_init()函数
static int __init of_platform_default_populate_init(void)
{
struct device_node *node;
//判断dtbhas been converted tostruct device_node结构体
if (!of_have_populated_dt())
return -ENODEV;
//解析reserved-memory节点,This node is to tell the kernel that this part of the memory is reserved,不要去使用
//Generally, this part of the memory is storeddtb数据本身
node = of_find_node_by_path("/reserved-memory");
if (node) {
node = of_find_compatible_node(node, NULL, "ramoops");
if (node)
of_platform_device_create(node, NULL, NULL);
}
/* 实例化每个device_node结构体成platform_device结构体 */
of_platform_default_populate(NULL, NULL, NULL);
return 0;
}
arch_initcall_sync(of_platform_default_populate_init);
(1)The function itself does not do the conversion work,Mainly to make some preliminary judgments,以及处理reserved-memory节点;
(2)arch_initcall_sync宏:将of_platform_default_populate_init函数赋予".initcall3s.init"段属性,结果就是of_platform_default_populate_initThe function will be called during the kernel boot process;
3、of_platform_populate()函数
/** * of_platform_bus_create() - Create a device for a node and its children. * @bus: device node of the bus to instantiate * @matches: match table for bus nodes * @lookup: auxdata table for matching id and platform_data with device nodes * @parent: parent for new device, or NULL for top level. * @strict: require compatible property * * Creates a platform_device for the provided device_node, and optionally * recursively create devices for all the child nodes. */
static int of_platform_bus_create(struct device_node *bus,
const struct of_device_id *matches,
const struct of_dev_auxdata *lookup,
struct device *parent, bool strict)
{
const struct of_dev_auxdata *auxdata;
struct device_node *child;
struct platform_device *dev;
const char *bus_id = NULL;
void *platform_data = NULL;
int rc = 0;
/* Make sure the node hascompatible属性,This is for matching with the bus*/
if (strict && (!of_get_property(bus, "compatible", NULL))) {
pr_debug("%s() - skipping %s, no compatible prop\n",
__func__, bus->full_name);
return 0;
}
//Check if the node has already been instantiated
if (of_node_check_flag(bus, OF_POPULATED_BUS)) {
pr_debug("%s() - skipping %s, already populated\n",
__func__, bus->full_name);
return 0;
}
//遍历节点,because it came inlookup是NULL,Actually this code doesn't work
auxdata = of_dev_lookup(lookup, bus);
if (auxdata) {
bus_id = auxdata->name;
platform_data = auxdata->platform_data;
}
//判断节点的compatible属性是否是"arm,primecell"
//如果compatibleIf the attribute matches, it means that the node needs to be registered toamba总线上
if (of_device_is_compatible(bus, "arm,primecell")) {
/* * Don't return an error here to keep compatibility with older * device tree files. */
of_amba_device_create(bus, bus_id, platform_data, parent);
return 0;
}
//将device_node结构体转换成platform_device结构体
dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent);
if (!dev || !of_match_node(matches, bus))
return 0;
//遍历节点的子节点,递归调用of_platform_bus_create()函数进行device_node转换
for_each_child_of_node(bus, child) {
pr_debug(" create child: %s\n", child->full_name);
rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict);
if (rc) {
of_node_put(child);
break;
}
}
//设置device_node节点的状态,Change to the state that has been registered with the bus
of_node_set_flag(bus, OF_POPULATED_BUS);
return rc;
}
4、of_platform_device_create_pdata()函数
static struct platform_device *of_platform_device_create_pdata(struct device_node *np,
const char *bus_id,void *platform_data,struct device *parent)
{
struct platform_device *dev;
//判断该节点的status属性是否是okay
//Set the flag bit of the nodeOF_POPULATED,indicates that it has been instantiated
if (!of_device_is_available(np) ||
of_node_test_and_set_flag(np, OF_POPULATED))
return NULL;
//定义并初始化一个platform_device结构体
//platform_deviceStructural Analysisdevice_node结构体进行填充
dev = of_device_alloc(np, bus_id, parent);
if (!dev)
goto err_clear_flag;
//Set the bus properties of a node to beplatform总线
dev->dev.bus = &platform_bus_type;
dev->dev.platform_data = platform_data;
of_dma_configure(&dev->dev, dev->dev.of_node);
of_msi_configure(&dev->dev, dev->dev.of_node);
//将构建的platform_device结构体注册到platform总线
if (of_device_add(dev) != 0) {
of_dma_deconfigure(&dev->dev);
platform_device_put(dev);
goto err_clear_flag;
}
return dev;
err_clear_flag:
of_node_clear_flag(np, OF_POPULATED);
return NULL;
}
5、of_device_alloc()函数
struct platform_device *of_device_alloc(struct device_node *np,
const char *bus_id,
struct device *parent)
{
struct platform_device *dev;
int rc, i, num_reg = 0, num_irq;
struct resource *res, temp_res;
//先申请一个platform_device结构体并初始化
dev = platform_device_alloc("", -1);
if (!dev)
return NULL;
/* 解析device_node中的IO、Number of interrupt resources */
while (of_address_to_resource(np, num_reg, &temp_res) == 0)
num_reg++;
num_irq = of_irq_count(np);
/* IO、interrupt the resource and convert toplatform_device结构中的resource */
if (num_irq || num_reg) {
res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
if (!res) {
platform_device_put(dev);
return NULL;
}
dev->num_resources = num_reg + num_irq;
dev->resource = res;
for (i = 0; i < num_reg; i++, res++) {
rc = of_address_to_resource(np, i, res);
WARN_ON(rc);
}
if (of_irq_to_resource_table(np, res, num_irq) != num_irq)
pr_debug("not all legacy IRQ resources mapped for %s\n",
np->name);
}
dev->dev.of_node = of_node_get(np);
dev->dev.fwnode = &np->fwnode;
dev->dev.parent = parent ? : &platform_bus;
if (bus_id)
dev_set_name(&dev->dev, "%s", bus_id);
else
of_device_make_bus_id(&dev->dev);
return dev;
}
EXPORT_SYMBOL(of_device_alloc);
边栏推荐
- Rasa 3.x Learning Series - Using Lookup Tables to Improve Entity Extraction
- Item 36: Specify std::launch::async if asynchronicity is essential.
- By Value or By Reference
- What is the meaning of JS timestamp?Know SQL will consider to add a timestamp, JS timestamp for the scene?
- 解决IDEA默认情况下新建文件时,右击,new,没有XML文件的问题
- ECCV2022 Workshop | 复杂环境中的多目标跟踪和分割
- Flink 部署和提交job
- 机器学习初学者可以学哪些实战项目?
- Rasa 3.x 学习系列- Rasa - Issues 4918 学习笔记
- OSD read SAP CRM One Order application log way of optimization
猜你喜欢
随机推荐
How is the tree structure of the device tree reflected?
Blueprint: Yang Hui's Triangular Arrangement
[Data analysis] Based on matlab GUI student achievement management system [including Matlab source code 1981]
【密码学/密码分析】基于TMTO的密码分析方法
RTL8762DK PWM(七)
LeetCode每日一练 —— 环形链表问题(面试四连问)
WeChat applet page syntax
OSD read SAP CRM One Order application log way of optimization
The principle of virtual inheritance
MYSQL-Batch insert data
数据中台建设(七):数据资产管理
设备树——dtb格式到struct device node结构体的转换
Carefully summarize thirteen suggestions to help you create more suitable MySQL indexes
VPGNet
从零造键盘的键盘超级喜欢,IT人最爱
Super like the keyboard made from zero, IT people love it
MYSQL关键字Explain解析
Unity3D study notes 10 - texture array
/usr/sbin/vmware-authdlauncher: error while loading shared libraries: libssl.so.1.0.2*解决办法
500 miles