目录

1. 提取指定属性的值

2. 根据属性值查找并读取32位整形数组

3. 根据属性值查找并读取字符串

4. 提取默认属性#address-cells和#size-cells的值

5. 通过路径查找节点

6. 通过节点名属性查找节点

7. 通过设备类型查找节点

8. 提取I/O口地址

9. 设备树中提取I/O口地址转换为物理地址;

10. 提取I/O口地址并映射成虚拟地址

11. 从设备树中提取资源


查找办法:

通过节点的compatible属性值查找指定节点;

通过节点名查找指定节点;

通过节点路径查找指定节点;

struct device_node结构体 

//头文件linux/of.h
//设备节点,描述设备数节点;
struct device_node {
	const char *name;//节点名
	const char *type;//设备类型
	phandle phandle;
	char	*full_name;//全路径节点名

	struct	property *properties;
	struct	property *deadprops;	/* removed properties */
	struct	device_node *parent; //父节点指针
	struct	device_node *child;  //子节点指针
	struct	device_node *sibling;//兄弟节点指针
	struct	device_node *next;	/* next device of same type */
	struct	device_node *allnext;	/* next in list of all nodes */
	struct	proc_dir_entry *pde;	/* this node's proc directory */
	struct	kref kref;
	unsigned long _flags;
	void	*data;
};

struct property结构体

struct property {
	char	*name; //属性名
	int	length;    //属性值的字节数
	void	*value;//属性值的首地址
	struct property *next;
	unsigned long _flags;
	unsigned int unique_id;
};

1. 提取指定属性的值

struct property *of_find_property(const struct device_node *np, //设备节点指针;
                        const char *name,  //需要查找的属性名;
                        int *lenp); //输出参数;非NULL则查找成功后被赋值为查找到的属性长度;

2. 根据属性值查找并读取32位整形数组

int of_property_read_u32_array(const struct device_node *np, //设备节点指针;
                       const char *propname, //需要查找的属性名;
                       u32 *out_values, //输出参数,存储查到的整形值
                       size_t sz);           //输出数组大小


成功:返回0; 属性不存在返回-EINVAL;属性没有值返回-ENODATA; 属性数据不够大返回-EOVERFLOW;

static inline int of_property_read_u32(const struct device_node *np,
				       const char *propname,
				       u32 *out_value)
{
	return of_property_read_u32_array(np, propname, out_value, 1);
}

of_property_read_u32 是 of_property_read_u32_array 的特殊形式;

3. 根据属性值查找并读取字符串

int of_property_read_string(struct device_node *np,//设备节点指针
                const char *propname,  //被查找的属性名
                 const char **out_string) ;//返回指向以null结尾的字符串指针



成功:返回0; 属性不存在返回-EINVAL;属性没有值返回-ENODATA; 字符串不是以null结尾返回-EILSEQ;

 

4. 提取默认属性#address-cells和#size-cells的值

int of_n_addr_cells(struct device_node *np);
int of_n_size_cells(struct device_node *np);

 

5. 通过路径查找节点

struct device_node *of_find_node_by_path(const char *path);

示例:
    struct device_node *np;
    np = of_find_node_by_path("/soc@ff000000/cpm@9c0/serial@a80");
    np = of_find_node_by_path("/");

内部是通过比较struct device_node的full_name成员;

6. 通过节点名属性查找节点

struct device_node *of_find_node_by_name(
                                struct device_node *from,//开始查找的节点或null
                                 const char *name)  //匹配的字符串名字;

 内部是通过比较struct device_node的name成员;

7. 通过设备类型查找节点

struct device_node *of_find_node_by_type(struct device_node *from,
     const char *type) //匹配的类型字符串;

 内部是通过比较struct device_node的type成员;

8. 提取I/O口地址

const u32 *of_get_address(struct device_node *dev, //设备节点
                                            int index,//地址编号
                                             u64 *size,//输出参数,I/O口地址的长度;                 unsigned int *flags);//输出参数,类型(IORESOURCE_IO,IORESOURCE_MEM)

9. 设备树中提取I/O口地址转换为物理地址;

of_translate_address(struct device_node *dev,
                                             const __be32 *in_addr);//设备树提取的I/O地址;

 

10. 提取I/O口地址并映射成虚拟地址

void __iomem *of_iomap(struct device_node *device, int index);

 

11. 从设备树中提取资源

int of_address_to_resource(struct device_node *dev, int index,
                struct resource *r); //输出参数,指向资源