目录
2. of_fwnode_ops 结构体提供了一组 “函数”
3. fwnode_xxx() 调用of_fwnode 函数的实现
概述
1. of_node_init(np)函数初始化了fwnode 变量
2. 初始化fwnode.ops =of_fwnode_ops 结构体(实际包含一组函数)
3. 类似 fwnode_xxx 的函数调用,实际调用了 ”of_fwnode_ops“结构体 提供的一组函数
4. of_fwnode_ops“结构体的fw_fwnode_xxx 最终调用of_xxx 函数
两个property.c 文件的说明
drivers/of/property.c 提供 of_xxx() 和 of_fwnode_xxx() 函数
drivers/base/property.c 提供 fwnode_xxx ()
实例
1. struct fwnode_handle *fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link");
2. fwnode_property_read_u32_array(fwnode, "fixed-link",NULL, 0);
3. fwnode_property_read_u32_array(fwnode, "fixed-link",prop, ARRAY_SIZE(prop));
1. 略
2. 未提供地址,则返回数组的成员数量
3. 略
代码分析
1. fwnode 变量的初始化
static bool populate_node(const void *blob,int offset,
void **mem, struct device_node *dad,
struct device_node **pnp, bool dryrun)
{
struct device_node *np;
const char *pathp;
unsigned int l, allocl;
pathp = fdt_get_name(blob, offset, &l);
if (!pathp) {
*pnp = NULL;
return false;
}
allocl = ++l;
np = unflatten_dt_alloc(mem, sizeof(struct device_node) + allocl,
__alignof__(struct device_node));
if (!dryrun) {
char *fn;
of_node_init(np); // 初始化 np->fwnode
np->full_name = fn = ((char *)np) + sizeof(*np); //填充np->full_name
memcpy(fn, pathp, l);
.......
}
.......
}
static inline void of_node_init(struct device_node *node)
{
#if defined(CONFIG_OF_KOBJ)
kobject_init(&node->kobj, &of_node_ktype);
#endif
node->fwnode.ops = &of_fwnode_ops; //填充具体的操作函数结构体of_fwnode_ops
}
2. of_fwnode_ops 结构体提供了一组 “函数”
const struct fwnode_operations of_fwnode_ops = {
.get = of_fwnode_get,
.put = of_fwnode_put,
.device_is_available = of_fwnode_device_is_available,
.device_get_match_data = of_fwnode_device_get_match_data,
.property_present = of_fwnode_property_present,
.property_read_int_array = of_fwnode_property_read_int_array,
.property_read_string_array = of_fwnode_property_read_string_array,
.get_parent = of_fwnode_get_parent,
.get_next_child_node = of_fwnode_get_next_child_node,
.get_named_child_node = of_fwnode_get_named_child_node,
.get_reference_args = of_fwnode_get_reference_args,
.graph_get_next_endpoint = of_fwnode_graph_get_next_endpoint,
.graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint,
.graph_get_port_parent = of_fwnode_graph_get_port_parent,
.graph_parse_endpoint = of_fwnode_graph_parse_endpoint,
};
3. fwnode_xxx() 调用of_fwnode 函数的实现
static int fwnode_property_read_int_array(const struct fwnode_handle *fwnode,
const char *propname,
unsigned int elem_size, void *val,
size_t nval)
{
int ret;
//利用宏组成fwnode->ops->property_read_int_array(fwnode,propname,elem_size,val,nval)
ret = fwnode_call_int_op(fwnode, property_read_int_array, propname,
elem_size, val, nval);
if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
!IS_ERR_OR_NULL(fwnode->secondary))
ret = fwnode_call_int_op(
fwnode->secondary, property_read_int_array, propname,
elem_size, val, nval);
return ret;
}