当前位置:网站首页>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总线的device;
(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);
边栏推荐
- cmake入门学习笔记
- MYSQL Keyword Explain Analysis
- Daily practice of LeetCode - Circular linked list question (interview four consecutive questions)
- Handwritten binary search tree and test
- MYSQL二阶段提交
- RTL8762DK WDG(六)
- Basic implementation of vector
- Unity3D study notes 10 - texture array
- 【历史上的今天】7 月 31 日:“缸中之脑”的提出者诞生;Wi-Fi 之父出生;USB 3.1 标准发布
- Nmap Operation Manual - Full Version
猜你喜欢
![[Microservice] Distributed Transaction Solution - Seata](/img/a8/fc6c24e4d42dfb635bad786cc02164.png)
[Microservice] Distributed Transaction Solution - Seata

微信小程序之小程序页面语法

RTL8762DK 点灯/LED(三)

MYSQL主从复制

pycaret source code analysis: download dataset\Lib\site-packages\pycaret\datasets.py

Euler system (euleros): upgrade Mysql

Blueprint: Yang Hui's Triangular Arrangement

蓝图:杨辉三角排列

Google Earth Engine - Error resolution of Error: Image.clipToBoundsAndScale, argument 'input': Invalid type

YOLO怎么入门?怎么实现自己的训练集?
随机推荐
Southern University of Science and Technology: Xiaoying Tang | AADG: Automatic Enhancement for Generalization in the Field of Retinal Image Segmentation
RTL8762DK UART (two)
Carefully summarize thirteen suggestions to help you create more suitable MySQL indexes
Flink 部署和提交job
Super like the keyboard made from zero, IT people love it
机器学习初学者可以学哪些实战项目?
[Microservice] Distributed Transaction Solution - Seata
An open source and easy-to-use flowchart drawing tool drawio
Academicians of the two academies speak bluntly: Don't be superstitious about academicians
sqlserver无法远程连接
Nmap 操作手册 - 完整版
RTL8762DK PWM(七)
七月集训(第31天) —— 状态压缩
SC7A20(士兰微-加速度传感器)示例
how to edit the table of contents of an epub ebook
Key Points Estimation and Point Instance
What practical projects can machine learning beginners learn?
C string array reverse
设备树——dtb格式到struct device node结构体的转换
MYSQL-批量插入数据