1 /*
2  * Copyright (c) 2020 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 #include <zephyr/devicetree.h>
9 #include <zephyr/device.h>
10 
11 #define TEST_GPIO DT_NODELABEL(test_gpio_0)
12 #define TEST_I2C DT_NODELABEL(test_i2c)
13 #define TEST_DEVA DT_NODELABEL(test_dev_a)
14 #define TEST_GPIOX DT_NODELABEL(test_gpiox)
15 #define TEST_DEVB DT_NODELABEL(test_dev_b)
16 #define TEST_DEVC DT_NODELABEL(test_dev_c)
17 #define TEST_PARTITION DT_NODELABEL(test_p0)
18 #define TEST_GPIO_INJECTED DT_NODELABEL(test_gpio_injected)
19 #define TEST_NOLABEL DT_PATH(test, i2c_11112222, test_i2c_dev_14)
20 
21 static const struct device *devlist;
22 static const struct device *devlist_end;
23 
24 static device_handle_t init_order[10];
25 
dev_init(const struct device * dev)26 static int dev_init(const struct device *dev)
27 {
28 	static uint8_t init_idx;
29 
30 	__ASSERT_NO_MSG(init_idx < ARRAY_SIZE(init_order));
31 	init_order[init_idx++] = device_handle_get(dev);
32 
33 	return 0;
34 }
35 
36 DEVICE_DT_DEFINE(TEST_GPIO, dev_init, NULL,
37 		 NULL, NULL, PRE_KERNEL_1, 90, NULL);
38 DEVICE_DT_DEFINE(TEST_I2C, dev_init, NULL,
39 		 NULL, NULL, POST_KERNEL, 10, NULL);
40 DEVICE_DT_DEFINE(TEST_DEVA, dev_init, NULL,
41 		 NULL, NULL, POST_KERNEL, 20, NULL);
42 /* NB: Intentional init devb before required gpiox */
43 DEVICE_DT_DEFINE(TEST_DEVB, dev_init, NULL,
44 		 NULL, NULL, POST_KERNEL, 30, NULL);
45 DEVICE_DT_DEFINE(TEST_GPIOX, dev_init, NULL,
46 		 NULL, NULL, POST_KERNEL, 40, NULL);
47 DEVICE_DT_DEFINE(TEST_DEVC, dev_init, NULL,
48 		 NULL, NULL, POST_KERNEL, 50, NULL);
49 DEVICE_DT_DEFINE(TEST_PARTITION, dev_init, NULL,
50 		 NULL, NULL, POST_KERNEL, 60, NULL);
51 /* Device with both an existing and missing injected dependency */
52 DEVICE_DT_DEFINE(TEST_GPIO_INJECTED, dev_init, NULL,
53 		 NULL, NULL, POST_KERNEL, 70, NULL, DT_DEP_ORD(TEST_DEVB), 999);
54 /* Manually specified device */
55 DEVICE_DEFINE(manual_dev, "Manual Device", dev_init, NULL,
56 		 NULL, NULL, POST_KERNEL, 80, NULL);
57 /* Device with no nodelabel */
58 DEVICE_DT_DEFINE(TEST_NOLABEL, dev_init, NULL,
59 		 NULL, NULL, POST_KERNEL, 90, NULL);
60 
61 #define DEV_HDL(node_id) device_handle_get(DEVICE_DT_GET(node_id))
62 #define DEV_HDL_NAME(name) device_handle_get(DEVICE_GET(name))
63 
ZTEST(devicetree_devices,test_init_get)64 ZTEST(devicetree_devices, test_init_get)
65 {
66 	/* Check device pointers */
67 	zassert_equal(DEVICE_INIT_DT_GET(TEST_GPIO)->dev,
68 		      DEVICE_DT_GET(TEST_GPIO), NULL);
69 	zassert_equal(DEVICE_INIT_DT_GET(TEST_I2C)->dev,
70 		      DEVICE_DT_GET(TEST_I2C), NULL);
71 	zassert_equal(DEVICE_INIT_DT_GET(TEST_DEVA)->dev,
72 		      DEVICE_DT_GET(TEST_DEVA), NULL);
73 	zassert_equal(DEVICE_INIT_DT_GET(TEST_DEVB)->dev,
74 		      DEVICE_DT_GET(TEST_DEVB), NULL);
75 	zassert_equal(DEVICE_INIT_DT_GET(TEST_GPIOX)->dev,
76 		      DEVICE_DT_GET(TEST_GPIOX), NULL);
77 	zassert_equal(DEVICE_INIT_DT_GET(TEST_DEVC)->dev,
78 		      DEVICE_DT_GET(TEST_DEVC), NULL);
79 	zassert_equal(DEVICE_INIT_DT_GET(TEST_PARTITION)->dev,
80 		      DEVICE_DT_GET(TEST_PARTITION), NULL);
81 	zassert_equal(DEVICE_INIT_DT_GET(TEST_GPIO_INJECTED)->dev,
82 		      DEVICE_DT_GET(TEST_GPIO_INJECTED), NULL);
83 	zassert_equal(DEVICE_INIT_GET(manual_dev)->dev,
84 		      DEVICE_GET(manual_dev), NULL);
85 	zassert_equal(DEVICE_INIT_DT_GET(TEST_NOLABEL)->dev,
86 		      DEVICE_DT_GET(TEST_NOLABEL), NULL);
87 
88 	/* Check init functions */
89 	zassert_equal(DEVICE_INIT_DT_GET(TEST_GPIO)->init_fn.dev, dev_init);
90 	zassert_equal(DEVICE_INIT_DT_GET(TEST_I2C)->init_fn.dev, dev_init);
91 	zassert_equal(DEVICE_INIT_DT_GET(TEST_DEVA)->init_fn.dev, dev_init);
92 	zassert_equal(DEVICE_INIT_DT_GET(TEST_DEVB)->init_fn.dev, dev_init);
93 	zassert_equal(DEVICE_INIT_DT_GET(TEST_GPIOX)->init_fn.dev, dev_init);
94 	zassert_equal(DEVICE_INIT_DT_GET(TEST_DEVC)->init_fn.dev, dev_init);
95 	zassert_equal(DEVICE_INIT_DT_GET(TEST_PARTITION)->init_fn.dev, dev_init);
96 	zassert_equal(DEVICE_INIT_DT_GET(TEST_GPIO_INJECTED)->init_fn.dev, dev_init);
97 	zassert_equal(DEVICE_INIT_GET(manual_dev)->init_fn.dev, dev_init);
98 	zassert_equal(DEVICE_INIT_DT_GET(TEST_NOLABEL)->init_fn.dev, dev_init);
99 }
100 
ZTEST(devicetree_devices,test_init_order)101 ZTEST(devicetree_devices, test_init_order)
102 {
103 	zassert_equal(init_order[0], DEV_HDL(TEST_GPIO));
104 	zassert_equal(init_order[1], DEV_HDL(TEST_I2C));
105 	zassert_equal(init_order[2], DEV_HDL(TEST_DEVA));
106 	zassert_equal(init_order[3], DEV_HDL(TEST_DEVB));
107 	zassert_equal(init_order[4], DEV_HDL(TEST_GPIOX));
108 	zassert_equal(init_order[5], DEV_HDL(TEST_DEVC));
109 	zassert_equal(init_order[6], DEV_HDL(TEST_PARTITION));
110 	zassert_equal(init_order[7], DEV_HDL(TEST_GPIO_INJECTED));
111 	zassert_equal(init_order[8], DEV_HDL_NAME(manual_dev));
112 	zassert_equal(init_order[9], DEV_HDL(TEST_NOLABEL));
113 }
114 
check_handle(device_handle_t hdl,const device_handle_t * hdls,size_t nhdls)115 static bool check_handle(device_handle_t hdl,
116 			 const device_handle_t *hdls,
117 			 size_t nhdls)
118 {
119 	const device_handle_t *hdle = hdls + nhdls;
120 
121 	while (hdls < hdle) {
122 		if (*hdls == hdl) {
123 			return true;
124 		}
125 		++hdls;
126 	}
127 
128 	return false;
129 }
130 
131 struct visitor_context {
132 	uint8_t ndevs;
133 	const struct device *rdevs[2];
134 };
135 
device_visitor(const struct device * dev,void * context)136 static int device_visitor(const struct device *dev,
137 			  void *context)
138 {
139 	struct visitor_context *ctx = context;
140 	const struct device **rdp = ctx->rdevs;
141 
142 	while (rdp < (ctx->rdevs + ctx->ndevs)) {
143 		if (*rdp == NULL) {
144 			*rdp = dev;
145 			return 0;
146 		}
147 
148 		++rdp;
149 	}
150 
151 	return -ENOSPC;
152 }
153 
ZTEST(devicetree_devices,test_requires)154 ZTEST(devicetree_devices, test_requires)
155 {
156 	size_t nhdls = 0;
157 	const device_handle_t *hdls;
158 	const struct device *dev;
159 	struct visitor_context ctx = { 0 };
160 
161 	/* TEST_GPIO: no req */
162 	dev = device_get_binding(DEVICE_DT_NAME(TEST_GPIO));
163 	zassert_equal(dev, DEVICE_DT_GET(TEST_GPIO));
164 	hdls = device_required_handles_get(dev, &nhdls);
165 	zassert_equal(nhdls, 0);
166 	zassert_equal(0, device_required_foreach(dev, device_visitor, &ctx),
167 		      NULL);
168 
169 	/* TEST_GPIO_INJECTED: no req */
170 	dev = device_get_binding(DEVICE_DT_NAME(TEST_GPIO_INJECTED));
171 	zassert_equal(dev, DEVICE_DT_GET(TEST_GPIO_INJECTED));
172 	hdls = device_required_handles_get(dev, &nhdls);
173 	zassert_equal(nhdls, 0);
174 	zassert_equal(0, device_required_foreach(dev, device_visitor, &ctx),
175 		      NULL);
176 
177 	/* TEST_I2C: no req */
178 	dev = device_get_binding(DEVICE_DT_NAME(TEST_I2C));
179 	zassert_equal(dev, DEVICE_DT_GET(TEST_I2C));
180 	hdls = device_required_handles_get(dev, &nhdls);
181 	zassert_equal(nhdls, 0);
182 	zassert_equal(0, device_required_foreach(dev, device_visitor, &ctx),
183 		      NULL);
184 
185 	/* TEST_DEVA: TEST_I2C GPIO */
186 	dev = device_get_binding(DEVICE_DT_NAME(TEST_DEVA));
187 	zassert_equal(dev, DEVICE_DT_GET(TEST_DEVA));
188 	hdls = device_required_handles_get(dev, &nhdls);
189 	zassert_equal(nhdls, 2);
190 	zassert_true(check_handle(DEV_HDL(TEST_I2C), hdls, nhdls));
191 	zassert_true(check_handle(DEV_HDL(TEST_GPIO), hdls, nhdls));
192 
193 	/* Visit fails if not enough space */
194 	ctx = (struct visitor_context){
195 		.ndevs = 1,
196 	};
197 	zassert_equal(-ENOSPC, device_required_foreach(dev, device_visitor, &ctx),
198 		      NULL);
199 
200 	/* Visit succeeds if enough space. */
201 	ctx = (struct visitor_context){
202 		.ndevs = 2,
203 	};
204 	zassert_equal(2, device_required_foreach(dev, device_visitor, &ctx),
205 		      NULL);
206 	zassert_true((ctx.rdevs[0] == device_from_handle(DEV_HDL(TEST_I2C)))
207 		     || (ctx.rdevs[1] == device_from_handle(DEV_HDL(TEST_I2C))),
208 		     NULL);
209 	zassert_true((ctx.rdevs[0] == device_from_handle(DEV_HDL(TEST_GPIO)))
210 		     || (ctx.rdevs[1] == device_from_handle(DEV_HDL(TEST_GPIO))),
211 		     NULL);
212 
213 	/* TEST_GPIOX: TEST_I2C */
214 	dev = device_get_binding(DEVICE_DT_NAME(TEST_GPIOX));
215 	zassert_equal(dev, DEVICE_DT_GET(TEST_GPIOX));
216 	hdls = device_required_handles_get(dev, &nhdls);
217 	zassert_equal(nhdls, 1);
218 	zassert_true(check_handle(DEV_HDL(TEST_I2C), hdls, nhdls));
219 	ctx = (struct visitor_context){
220 		.ndevs = 3,
221 	};
222 	zassert_equal(1, device_required_foreach(dev, device_visitor, &ctx),
223 		      NULL);
224 	zassert_true(ctx.rdevs[0] == device_from_handle(DEV_HDL(TEST_I2C)),
225 		     NULL);
226 
227 	/* TEST_DEVB: TEST_I2C TEST_GPIOX */
228 	dev = device_get_binding(DEVICE_DT_NAME(TEST_DEVB));
229 	zassert_equal(dev, DEVICE_DT_GET(TEST_DEVB));
230 	hdls = device_required_handles_get(dev, &nhdls);
231 	zassert_equal(nhdls, 2);
232 	zassert_true(check_handle(DEV_HDL(TEST_I2C), hdls, nhdls));
233 	zassert_true(check_handle(DEV_HDL(TEST_GPIOX), hdls, nhdls));
234 
235 	/* TEST_GPIO_INJECTED: NONE */
236 	dev = device_get_binding(DEVICE_DT_NAME(TEST_GPIO_INJECTED));
237 	zassert_equal(dev, DEVICE_DT_GET(TEST_GPIO_INJECTED));
238 	hdls = device_required_handles_get(dev, &nhdls);
239 	zassert_equal(nhdls, 0);
240 }
241 
ZTEST(devicetree_devices,test_injected)242 ZTEST(devicetree_devices, test_injected)
243 {
244 	size_t nhdls = 0;
245 	const device_handle_t *hdls;
246 	const struct device *dev;
247 
248 	/* TEST_GPIO: NONE */
249 	dev = device_get_binding(DEVICE_DT_NAME(TEST_GPIO));
250 	hdls = device_injected_handles_get(dev, &nhdls);
251 	zassert_equal(nhdls, 0);
252 
253 	/* TEST_DEVB: NONE */
254 	dev = device_get_binding(DEVICE_DT_NAME(TEST_DEVB));
255 	hdls = device_injected_handles_get(dev, &nhdls);
256 	zassert_equal(nhdls, 0);
257 
258 	/* TEST_GPIO_INJECTED: TEST_DEVB */
259 	dev = device_get_binding(DEVICE_DT_NAME(TEST_GPIO_INJECTED));
260 	hdls = device_injected_handles_get(dev, &nhdls);
261 	zassert_equal(nhdls, 1);
262 	zassert_true(check_handle(DEV_HDL(TEST_DEVB), hdls, nhdls));
263 }
264 
ZTEST(devicetree_devices,test_get_or_null)265 ZTEST(devicetree_devices, test_get_or_null)
266 {
267 	const struct device *dev;
268 
269 	dev = DEVICE_DT_GET_OR_NULL(TEST_DEVA);
270 	zassert_not_equal(dev, NULL, NULL);
271 
272 	dev = DEVICE_DT_GET_OR_NULL(non_existing_node);
273 	zassert_is_null(dev);
274 }
275 
ZTEST(devicetree_devices,test_supports)276 ZTEST(devicetree_devices, test_supports)
277 {
278 	size_t nhdls = 0;
279 	const device_handle_t *hdls;
280 	const struct device *dev;
281 	struct visitor_context ctx = { 0 };
282 
283 	/* TEST_DEVB: None */
284 	dev = DEVICE_DT_GET(TEST_DEVB);
285 	hdls = device_supported_handles_get(dev, &nhdls);
286 	zassert_equal(nhdls, 1);
287 	zassert_true(check_handle(DEV_HDL(TEST_GPIO_INJECTED), hdls, nhdls));
288 
289 	/* TEST_GPIO_INJECTED: None */
290 	dev = DEVICE_DT_GET(TEST_GPIO_INJECTED);
291 	hdls = device_supported_handles_get(dev, &nhdls);
292 	zassert_equal(nhdls, 0);
293 
294 	/* TEST_GPIO: TEST_DEVA */
295 	dev = DEVICE_DT_GET(TEST_GPIO);
296 	hdls = device_supported_handles_get(dev, &nhdls);
297 	zassert_equal(nhdls, 1);
298 	zassert_true(check_handle(DEV_HDL(TEST_DEVA), hdls, nhdls));
299 
300 	/* Visit fails if not enough space */
301 	ctx = (struct visitor_context){
302 		.ndevs = 0,
303 	};
304 	zassert_equal(-ENOSPC, device_supported_foreach(dev, device_visitor, &ctx));
305 
306 	/* Visit succeeds if enough space. */
307 	ctx = (struct visitor_context){
308 		.ndevs = 1,
309 	};
310 	zassert_equal(1, device_supported_foreach(dev, device_visitor, &ctx));
311 	zassert_true(ctx.rdevs[0] == device_from_handle(DEV_HDL(TEST_DEVA)));
312 
313 	/* TEST_I2C: TEST_DEVA TEST_GPIOX TEST_DEVB TEST_DEVC */
314 	dev = DEVICE_DT_GET(TEST_I2C);
315 	hdls = device_supported_handles_get(dev, &nhdls);
316 	zassert_equal(nhdls, 5);
317 	zassert_true(check_handle(DEV_HDL(TEST_DEVA), hdls, nhdls));
318 	zassert_true(check_handle(DEV_HDL(TEST_GPIOX), hdls, nhdls));
319 	zassert_true(check_handle(DEV_HDL(TEST_DEVB), hdls, nhdls));
320 	zassert_true(check_handle(DEV_HDL(TEST_DEVC), hdls, nhdls));
321 	zassert_true(check_handle(DEV_HDL(TEST_NOLABEL), hdls, nhdls));
322 
323 	/* Support forwarding (intermediate missing devicetree node)
324 	 * TEST_DEVC: TEST_PARTITION
325 	 */
326 	dev = DEVICE_DT_GET(TEST_DEVC);
327 	hdls = device_supported_handles_get(dev, &nhdls);
328 	zassert_equal(nhdls, 1);
329 	zassert_true(check_handle(DEV_HDL(TEST_PARTITION), hdls, nhdls));
330 }
331 
devicetree_devices_setup(void)332 void *devicetree_devices_setup(void)
333 {
334 	size_t ndevs;
335 
336 	ndevs = z_device_get_all_static(&devlist);
337 	devlist_end = devlist + ndevs;
338 
339 	return NULL;
340 }
341 ZTEST_SUITE(devicetree_devices, NULL, devicetree_devices_setup, NULL, NULL, NULL);
342