linux设备树- device_node的 fwnode的作用

目录

概述

实例

代码分析

1. fwnode  变量的初始化

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;
}

  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐分享-程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值