1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2 *
3 * Copyright 2010-2016 Freescale Semiconductor, Inc.
4 * Copyright 2017 NXP
5 *
6 */
7
8 #ifndef __OF_H
9 #define __OF_H
10
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdbool.h>
15 #include <stdlib.h>
16 #include <inttypes.h>
17 #include <sys/stat.h>
18 #include <sys/types.h>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <glob.h>
22 #include <errno.h>
23 #include <ctype.h>
24 #include <limits.h>
25 #include <rte_common.h>
26 #include <dpaa_list.h>
27 #include <rte_compat.h>
28
29 #ifndef OF_INIT_DEFAULT_PATH
30 #define OF_INIT_DEFAULT_PATH "/proc/device-tree"
31 #endif
32
33 #define OF_DEFAULT_NA 1
34 #define OF_DEFAULT_NS 1
35
36 #define OF_FILE_BUF_MAX 256
37
38 /**
39 * Layout of Device Tree:
40 * dt_dir
41 * |- dt_dir
42 * | |- dt_dir
43 * | | |- dt_dir
44 * | | | |- dt_file
45 * | | | ``- dt_file
46 * | | ``- dt_file
47 * | `-dt_file`
48 * ``- dt_file
49 *
50 * +------------------+
51 * |dt_dir |
52 * |+----------------+|
53 * ||dt_node ||
54 * ||+--------------+||
55 * |||device_node |||
56 * ||+--------------+||
57 * || list_dt_nodes ||
58 * |+----------------+|
59 * | list of subdir |
60 * | list of files |
61 * +------------------+
62 */
63
64 /**
65 * Device description on of a device node in device tree.
66 */
67 struct device_node {
68 char name[NAME_MAX];
69 char full_name[PATH_MAX];
70 };
71
72 /**
73 * List of device nodes available in a device tree layout
74 */
75 struct dt_node {
76 struct device_node node; /**< Property of node */
77 int is_file; /**< FALSE==dir, TRUE==file */
78 struct list_head list; /**< Nodes within a parent subdir */
79 };
80
81 /**
82 * Types we use to represent directories and files
83 */
84 struct dt_file;
85 struct dt_dir {
86 struct dt_node node;
87 struct list_head subdirs;
88 struct list_head files;
89 struct list_head linear;
90 struct dt_dir *parent;
91 struct dt_file *compatible;
92 struct dt_file *status;
93 struct dt_file *lphandle;
94 struct dt_file *a_cells;
95 struct dt_file *s_cells;
96 struct dt_file *reg;
97 };
98
99 struct dt_file {
100 struct dt_node node;
101 struct dt_dir *parent;
102 ssize_t len;
103 uint64_t buf[OF_FILE_BUF_MAX >> 3];
104 };
105
106 __rte_internal
107 const struct device_node *of_find_compatible_node(
108 const struct device_node *from,
109 const char *type __rte_unused,
110 const char *compatible)
111 __attribute__((nonnull(3)));
112
113 #define for_each_compatible_node(dev_node, type, compatible) \
114 for (dev_node = of_find_compatible_node(NULL, type, compatible); \
115 dev_node != NULL; \
116 dev_node = of_find_compatible_node(dev_node, type, compatible))
117
118 __rte_internal
119 const void *of_get_property(const struct device_node *from, const char *name,
120 size_t *lenp) __attribute__((nonnull(2)));
121 __rte_internal
122 bool of_device_is_available(const struct device_node *dev_node);
123
124 __rte_internal
125 const struct device_node *of_find_node_by_phandle(uint64_t ph);
126
127 __rte_internal
128 const struct device_node *of_get_parent(const struct device_node *dev_node);
129
130 __rte_internal
131 const struct device_node *of_get_next_child(const struct device_node *dev_node,
132 const struct device_node *prev);
133
134 __rte_internal
135 const void *of_get_mac_address(const struct device_node *np);
136
137 #define for_each_child_node(parent, child) \
138 for (child = of_get_next_child(parent, NULL); child != NULL; \
139 child = of_get_next_child(parent, child))
140
141 __rte_internal
142 uint32_t of_n_addr_cells(const struct device_node *dev_node);
143 uint32_t of_n_size_cells(const struct device_node *dev_node);
144
145 __rte_internal
146 const uint32_t *of_get_address(const struct device_node *dev_node, size_t idx,
147 uint64_t *size, uint32_t *flags);
148
149 __rte_internal
150 uint64_t of_translate_address(const struct device_node *dev_node,
151 const uint32_t *addr) __attribute__((nonnull));
152
153 __rte_internal
154 bool of_device_is_compatible(const struct device_node *dev_node,
155 const char *compatible);
156
157 /* of_init() must be called prior to initialisation or use of any driver
158 * subsystem that is device-tree-dependent. Eg. Qman/Bman, config layers, etc.
159 * The path should usually be "/proc/device-tree".
160 */
161 __rte_internal
162 int of_init_path(const char *dt_path);
163
164 /* of_finish() allows a controlled tear-down of the device-tree layer, eg. if a
165 * full reload is desired without a process exit.
166 */
167 void of_finish(void);
168
169 /* Use of this wrapper is recommended. */
of_init(void)170 static inline int of_init(void)
171 {
172 return of_init_path(OF_INIT_DEFAULT_PATH);
173 }
174
175 /* Read a numeric property according to its size and return it as a 64-bit
176 * value.
177 */
of_read_number(const uint32_t * cell,int size)178 static inline uint64_t of_read_number(const uint32_t *cell, int size)
179 {
180 uint64_t r = 0;
181
182 while (size--)
183 r = (r << 32) | be32toh(*(cell++));
184 return r;
185 }
186
187 #endif /* __OF_H */
188