目录
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); //输出参数,指向资源