当前位置:网站首页>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);
边栏推荐
- RTL8762DK PWM(七)
- MYSQL索引解析
- [Data analysis] Based on matlab GUI student achievement management system [including Matlab source code 1981]
- C string array reverse
- Google engineer fired for claiming AI awareness: breach of nondisclosure agreement
- RTL8762DK Lighting/LED (3)
- VPGNet
- leetcode: 1562. Find latest grouping of size M [simulation + endpoint record + range merge]
- RTL8762DK uses DebugAnalyzer (four)
- MYSQL二阶段提交
猜你喜欢

Unity3D study notes 10 - texture array

Classes and Objects: Medium

机器学习初学者可以学哪些实战项目?

Blueprint: Yang Hui's Triangular Arrangement

从零造键盘的键盘超级喜欢,IT人最爱

【历史上的今天】7 月 31 日:“缸中之脑”的提出者诞生;Wi-Fi 之父出生;USB 3.1 标准发布

【 】 today in history: on July 31, "brains in vats" the birth of the participant;The father of wi-fi was born;USB 3.1 standard

Academicians of the two academies speak bluntly: Don't be superstitious about academicians

how to edit the table of contents of an epub ebook

leetcode:1648. 销售价值减少的颜色球【二分找边界】
随机推荐
how to edit the table of contents of an epub ebook
RTL8762DK 使用DebugAnalyzer(四)
Unity3D学习笔记10——纹理数组
设计消息队列存储消息数据的MySQL表格
The IDEA can't find or unable to load The main class or Module "*" must not contain The source root "*" The root already belongs to The Module "*"
WeChat applet page syntax
GDB source code analysis series of articles five: dynamic library delay breakpoint implementation mechanism
设备树的树形结构到底是怎样体现的?
【 】 today in history: on July 31, "brains in vats" the birth of the participant;The father of wi-fi was born;USB 3.1 standard
Detailed explanation of TCP protocol
两院院士直言:不要迷信院士
Cmake introductory study notes
Web3.0:构建 NFT 市场(一)
Four ways the Metaverse is changing the way humans work
RTL8762DK WDG(六)
MYSQL-Batch insert data
Fat interface in JQESAP system
An open source and easy-to-use flowchart drawing tool drawio
RTL8762DK Lighting/LED (3)
机器学习应该如何入门?