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