blob: 959b834576ffd6e88b5e60b05879c8c47dc02c63 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glassb2c1cac2014-02-26 15:59:21 -07002/*
3 * Tests for the core driver model code
4 *
5 * Copyright (c) 2013 Google, Inc
Simon Glassb2c1cac2014-02-26 15:59:21 -07006 */
7
Simon Glassb2c1cac2014-02-26 15:59:21 -07008#include <errno.h>
9#include <dm.h>
10#include <fdtdec.h>
Simon Glass0f2af882020-05-10 11:40:05 -060011#include <log.h>
Simon Glassb2c1cac2014-02-26 15:59:21 -070012#include <malloc.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060013#include <asm/global_data.h>
Simon Glassb2c1cac2014-02-26 15:59:21 -070014#include <dm/device-internal.h>
15#include <dm/root.h>
Simon Glassb2c1cac2014-02-26 15:59:21 -070016#include <dm/util.h>
17#include <dm/test.h>
18#include <dm/uclass-internal.h>
Sughosh Ganu6012c1e2024-07-30 16:41:32 +053019#include <linux/list.h>
Simon Glass75c4d412020-07-19 10:15:37 -060020#include <test/test.h>
Joe Hershberger3a77be52015-05-20 14:27:27 -050021#include <test/ut.h>
Simon Glassb2c1cac2014-02-26 15:59:21 -070022
23DECLARE_GLOBAL_DATA_PTR;
24
25enum {
26 TEST_INTVAL1 = 0,
27 TEST_INTVAL2 = 3,
28 TEST_INTVAL3 = 6,
29 TEST_INTVAL_MANUAL = 101112,
Simon Glassfef72b72014-07-23 06:55:03 -060030 TEST_INTVAL_PRE_RELOC = 7,
Simon Glassb2c1cac2014-02-26 15:59:21 -070031};
32
33static const struct dm_test_pdata test_pdata[] = {
34 { .ping_add = TEST_INTVAL1, },
35 { .ping_add = TEST_INTVAL2, },
36 { .ping_add = TEST_INTVAL3, },
37};
38
39static const struct dm_test_pdata test_pdata_manual = {
40 .ping_add = TEST_INTVAL_MANUAL,
41};
42
Simon Glassfef72b72014-07-23 06:55:03 -060043static const struct dm_test_pdata test_pdata_pre_reloc = {
44 .ping_add = TEST_INTVAL_PRE_RELOC,
45};
46
Simon Glass1d8364a2020-12-28 20:34:54 -070047U_BOOT_DRVINFO(dm_test_info1) = {
Simon Glassb2c1cac2014-02-26 15:59:21 -070048 .name = "test_drv",
Simon Glass71fa5b42020-12-03 16:55:18 -070049 .plat = &test_pdata[0],
Simon Glassb2c1cac2014-02-26 15:59:21 -070050};
51
Simon Glass1d8364a2020-12-28 20:34:54 -070052U_BOOT_DRVINFO(dm_test_info2) = {
Simon Glassb2c1cac2014-02-26 15:59:21 -070053 .name = "test_drv",
Simon Glass71fa5b42020-12-03 16:55:18 -070054 .plat = &test_pdata[1],
Simon Glassb2c1cac2014-02-26 15:59:21 -070055};
56
Simon Glass1d8364a2020-12-28 20:34:54 -070057U_BOOT_DRVINFO(dm_test_info3) = {
Simon Glassb2c1cac2014-02-26 15:59:21 -070058 .name = "test_drv",
Simon Glass71fa5b42020-12-03 16:55:18 -070059 .plat = &test_pdata[2],
Simon Glassb2c1cac2014-02-26 15:59:21 -070060};
61
62static struct driver_info driver_info_manual = {
63 .name = "test_manual_drv",
Simon Glass71fa5b42020-12-03 16:55:18 -070064 .plat = &test_pdata_manual,
Simon Glassb2c1cac2014-02-26 15:59:21 -070065};
66
Simon Glassfef72b72014-07-23 06:55:03 -060067static struct driver_info driver_info_pre_reloc = {
68 .name = "test_pre_reloc_drv",
Simon Glass71fa5b42020-12-03 16:55:18 -070069 .plat = &test_pdata_pre_reloc,
Simon Glassfef72b72014-07-23 06:55:03 -060070};
71
Stefan Roeseeaffda72017-03-27 11:02:43 +020072static struct driver_info driver_info_act_dma = {
73 .name = "test_act_dma_drv",
74};
75
Marek Vasutabbdbbd2021-01-24 14:32:46 -070076static struct driver_info driver_info_vital_clk = {
77 .name = "test_vital_clk_drv",
78};
79
80static struct driver_info driver_info_act_dma_vital_clk = {
81 .name = "test_act_dma_vital_clk_drv",
82};
83
Joe Hershberger3a77be52015-05-20 14:27:27 -050084void dm_leak_check_start(struct unit_test_state *uts)
Simon Glass0927a6f2014-10-04 11:29:50 -060085{
Joe Hershberger3a77be52015-05-20 14:27:27 -050086 uts->start = mallinfo();
87 if (!uts->start.uordblks)
Simon Glass0927a6f2014-10-04 11:29:50 -060088 puts("Warning: Please add '#define DEBUG' to the top of common/dlmalloc.c\n");
89}
90
Joe Hershberger3a77be52015-05-20 14:27:27 -050091int dm_leak_check_end(struct unit_test_state *uts)
Simon Glass0927a6f2014-10-04 11:29:50 -060092{
93 struct mallinfo end;
Simon Glass94d22182015-09-12 08:45:20 -060094 int id, diff;
Simon Glass0927a6f2014-10-04 11:29:50 -060095
96 /* Don't delete the root class, since we started with that */
97 for (id = UCLASS_ROOT + 1; id < UCLASS_COUNT; id++) {
98 struct uclass *uc;
99
100 uc = uclass_find(id);
101 if (!uc)
102 continue;
103 ut_assertok(uclass_destroy(uc));
104 }
105
106 end = mallinfo();
Simon Glass94d22182015-09-12 08:45:20 -0600107 diff = end.uordblks - uts->start.uordblks;
108 if (diff > 0)
109 printf("Leak: lost %#xd bytes\n", diff);
110 else if (diff < 0)
111 printf("Leak: gained %#xd bytes\n", -diff);
Joe Hershberger3a77be52015-05-20 14:27:27 -0500112 ut_asserteq(uts->start.uordblks, end.uordblks);
Simon Glass0927a6f2014-10-04 11:29:50 -0600113
114 return 0;
115}
116
Simon Glass71fa5b42020-12-03 16:55:18 -0700117/* Test that binding with plat occurs correctly */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500118static int dm_test_autobind(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700119{
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200120 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700121
122 /*
123 * We should have a single class (UCLASS_ROOT) and a single root
124 * device with no children.
125 */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700126 ut_assert(uts->root);
Sughosh Ganu6012c1e2024-07-30 16:41:32 +0530127 ut_asserteq(1, list_count_nodes(gd->uclass_root));
128 ut_asserteq(0, list_count_nodes(&gd->dm_root->child_head));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700129 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]);
130
Simon Glassb75b15b2020-12-03 16:55:23 -0700131 ut_assertok(dm_scan_plat(false));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700132
133 /* We should have our test class now at least, plus more children */
Sughosh Ganu6012c1e2024-07-30 16:41:32 +0530134 ut_assert(1 < list_count_nodes(gd->uclass_root));
135 ut_assert(0 < list_count_nodes(&gd->dm_root->child_head));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700136
137 /* Our 3 dm_test_infox children should be bound to the test uclass */
138 ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_BIND]);
139
140 /* No devices should be probed */
141 list_for_each_entry(dev, &gd->dm_root->child_head, sibling_node)
Simon Glass6211d762020-12-19 10:40:10 -0700142 ut_assert(!(dev_get_flags(dev) & DM_FLAG_ACTIVATED));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700143
144 /* Our test driver should have been bound 3 times */
145 ut_assert(dm_testdrv_op_count[DM_TEST_OP_BIND] == 3);
146
147 return 0;
148}
149DM_TEST(dm_test_autobind, 0);
150
Simon Glass71fa5b42020-12-03 16:55:18 -0700151/* Test that binding with uclass plat allocation occurs correctly */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500152static int dm_test_autobind_uclass_pdata_alloc(struct unit_test_state *uts)
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200153{
154 struct dm_test_perdev_uc_pdata *uc_pdata;
155 struct udevice *dev;
156 struct uclass *uc;
157
158 ut_assertok(uclass_get(UCLASS_TEST, &uc));
159 ut_assert(uc);
160
161 /**
162 * Test if test uclass driver requires allocation for the uclass
Simon Glass71fa5b42020-12-03 16:55:18 -0700163 * platform data and then check the dev->uclass_plat pointer.
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200164 */
Simon Glass71fa5b42020-12-03 16:55:18 -0700165 ut_assert(uc->uc_drv->per_device_plat_auto);
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200166
167 for (uclass_find_first_device(UCLASS_TEST, &dev);
168 dev;
169 uclass_find_next_device(&dev)) {
Heinrich Schuchardt6c2a8712020-07-17 00:20:14 +0200170 ut_assertnonnull(dev);
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200171
Simon Glass71fa5b42020-12-03 16:55:18 -0700172 uc_pdata = dev_get_uclass_plat(dev);
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200173 ut_assert(uc_pdata);
174 }
175
176 return 0;
177}
Simon Glass1a92f832024-08-22 07:57:48 -0600178DM_TEST(dm_test_autobind_uclass_pdata_alloc, UTF_SCAN_PDATA);
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200179
Kishon Vijay Abraham Iae93e8a2021-07-21 21:28:31 +0530180/* compare node names ignoring the unit address */
181static int dm_test_compare_node_name(struct unit_test_state *uts)
182{
183 ofnode node;
184
185 node = ofnode_path("/mmio-bus@0");
186 ut_assert(ofnode_valid(node));
187 ut_assert(ofnode_name_eq(node, "mmio-bus"));
188
Simon Glass6dc1eb32025-01-10 17:00:27 -0700189 ut_assert(!ofnode_name_eq(node, "mmio-bus@0"));
190
Kishon Vijay Abraham Iae93e8a2021-07-21 21:28:31 +0530191 return 0;
192}
Simon Glass1a92f832024-08-22 07:57:48 -0600193DM_TEST(dm_test_compare_node_name, UTF_SCAN_PDATA);
Kishon Vijay Abraham Iae93e8a2021-07-21 21:28:31 +0530194
Simon Glass9d300ce2025-01-10 17:00:28 -0700195/* compare node names ignoring the unit address */
196static int dm_test_compare_node_name_unit(struct unit_test_state *uts)
197{
198 ofnode node;
199
200 node = ofnode_path("/mmio-bus@0");
201 ut_assert(ofnode_valid(node));
202 ut_assert(ofnode_name_eq_unit(node, "mmio-bus"));
203
204 ut_assert(ofnode_name_eq_unit(node, "mmio-bus@0"));
205 ut_assert(!ofnode_name_eq_unit(node, "mmio-bus@1"));
206 ut_assert(!ofnode_name_eq_unit(node, "mmio-bu"));
207 ut_assert(!ofnode_name_eq_unit(node, "mmio-buss@0"));
208
209 return 0;
210}
211DM_TEST(dm_test_compare_node_name_unit, UTF_SCAN_PDATA);
212
Simon Glass71fa5b42020-12-03 16:55:18 -0700213/* Test that binding with uclass plat setting occurs correctly */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500214static int dm_test_autobind_uclass_pdata_valid(struct unit_test_state *uts)
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200215{
216 struct dm_test_perdev_uc_pdata *uc_pdata;
217 struct udevice *dev;
218
219 /**
220 * In the test_postbind() method of test uclass driver, the uclass
221 * platform data should be set to three test int values - test it.
222 */
223 for (uclass_find_first_device(UCLASS_TEST, &dev);
224 dev;
225 uclass_find_next_device(&dev)) {
Heinrich Schuchardt6c2a8712020-07-17 00:20:14 +0200226 ut_assertnonnull(dev);
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200227
Simon Glass71fa5b42020-12-03 16:55:18 -0700228 uc_pdata = dev_get_uclass_plat(dev);
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200229 ut_assert(uc_pdata);
230 ut_assert(uc_pdata->intval1 == TEST_UC_PDATA_INTVAL1);
231 ut_assert(uc_pdata->intval2 == TEST_UC_PDATA_INTVAL2);
232 ut_assert(uc_pdata->intval3 == TEST_UC_PDATA_INTVAL3);
233 }
234
235 return 0;
236}
Simon Glass1a92f832024-08-22 07:57:48 -0600237DM_TEST(dm_test_autobind_uclass_pdata_valid, UTF_SCAN_PDATA);
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200238
Simon Glassb2c1cac2014-02-26 15:59:21 -0700239/* Test that autoprobe finds all the expected devices */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500240static int dm_test_autoprobe(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700241{
242 int expected_base_add;
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200243 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700244 struct uclass *uc;
245 int i;
246
247 ut_assertok(uclass_get(UCLASS_TEST, &uc));
248 ut_assert(uc);
249
250 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
Simon Glass9c1f3822015-03-05 12:25:22 -0700251 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700252 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
253
254 /* The root device should not be activated until needed */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700255 ut_assert(dev_get_flags(uts->root) & DM_FLAG_ACTIVATED);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700256
257 /*
258 * We should be able to find the three test devices, and they should
259 * all be activated as they are used (lazy activation, required by
260 * U-Boot)
261 */
262 for (i = 0; i < 3; i++) {
263 ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
264 ut_assert(dev);
Simon Glass6211d762020-12-19 10:40:10 -0700265 ut_assertf(!(dev_get_flags(dev) & DM_FLAG_ACTIVATED),
Simon Glassb2c1cac2014-02-26 15:59:21 -0700266 "Driver %d/%s already activated", i, dev->name);
267
268 /* This should activate it */
269 ut_assertok(uclass_get_device(UCLASS_TEST, i, &dev));
270 ut_assert(dev);
Simon Glass6211d762020-12-19 10:40:10 -0700271 ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700272
273 /* Activating a device should activate the root device */
274 if (!i)
Simon Glassb98bfbc2021-03-07 17:34:57 -0700275 ut_assert(dev_get_flags(uts->root) & DM_FLAG_ACTIVATED);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700276 }
277
Simon Glass9c1f3822015-03-05 12:25:22 -0700278 /*
279 * Our 3 dm_test_info children should be passed to pre_probe and
280 * post_probe
281 */
Simon Glassb2c1cac2014-02-26 15:59:21 -0700282 ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
Simon Glass9c1f3822015-03-05 12:25:22 -0700283 ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700284
285 /* Also we can check the per-device data */
286 expected_base_add = 0;
287 for (i = 0; i < 3; i++) {
288 struct dm_test_uclass_perdev_priv *priv;
289 struct dm_test_pdata *pdata;
290
291 ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
292 ut_assert(dev);
293
Simon Glassde0977b2015-03-05 12:25:20 -0700294 priv = dev_get_uclass_priv(dev);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700295 ut_assert(priv);
296 ut_asserteq(expected_base_add, priv->base_add);
297
Simon Glass95588622020-12-22 19:30:28 -0700298 pdata = dev_get_plat(dev);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700299 expected_base_add += pdata->ping_add;
300 }
301
302 return 0;
303}
Simon Glass1a92f832024-08-22 07:57:48 -0600304DM_TEST(dm_test_autoprobe, UTF_SCAN_PDATA);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700305
Simon Glass71fa5b42020-12-03 16:55:18 -0700306/* Check that we see the correct plat in each device */
Simon Glassb75b15b2020-12-03 16:55:23 -0700307static int dm_test_plat(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700308{
309 const struct dm_test_pdata *pdata;
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200310 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700311 int i;
312
313 for (i = 0; i < 3; i++) {
314 ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
315 ut_assert(dev);
Simon Glass95588622020-12-22 19:30:28 -0700316 pdata = dev_get_plat(dev);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700317 ut_assert(pdata->ping_add == test_pdata[i].ping_add);
318 }
319
320 return 0;
321}
Simon Glass1a92f832024-08-22 07:57:48 -0600322DM_TEST(dm_test_plat, UTF_SCAN_PDATA);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700323
324/* Test that we can bind, probe, remove, unbind a driver */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500325static int dm_test_lifecycle(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700326{
327 int op_count[DM_TEST_OP_COUNT];
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200328 struct udevice *dev, *test_dev;
Simon Glass51608c92021-12-16 20:59:32 -0700329 int start_dev_count, start_uc_count;
330 int dev_count, uc_count;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700331 int pingret;
332 int ret;
333
334 memcpy(op_count, dm_testdrv_op_count, sizeof(op_count));
335
Simon Glass51608c92021-12-16 20:59:32 -0700336 dm_get_stats(&start_dev_count, &start_uc_count);
337
Simon Glassb98bfbc2021-03-07 17:34:57 -0700338 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700339 &dev));
340 ut_assert(dev);
341 ut_assert(dm_testdrv_op_count[DM_TEST_OP_BIND]
342 == op_count[DM_TEST_OP_BIND] + 1);
Simon Glass95588622020-12-22 19:30:28 -0700343 ut_assert(!dev_get_priv(dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700344
Simon Glass51608c92021-12-16 20:59:32 -0700345 /* We should have one more device */
346 dm_get_stats(&dev_count, &uc_count);
347 ut_asserteq(start_dev_count + 1, dev_count);
348 ut_asserteq(start_uc_count, uc_count);
349
Simon Glassb2c1cac2014-02-26 15:59:21 -0700350 /* Probe the device - it should fail allocating private data */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700351 uts->force_fail_alloc = 1;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700352 ret = device_probe(dev);
353 ut_assert(ret == -ENOMEM);
354 ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE]
355 == op_count[DM_TEST_OP_PROBE] + 1);
Simon Glass95588622020-12-22 19:30:28 -0700356 ut_assert(!dev_get_priv(dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700357
358 /* Try again without the alloc failure */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700359 uts->force_fail_alloc = 0;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700360 ut_assertok(device_probe(dev));
361 ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE]
362 == op_count[DM_TEST_OP_PROBE] + 2);
Simon Glass95588622020-12-22 19:30:28 -0700363 ut_assert(dev_get_priv(dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700364
365 /* This should be device 3 in the uclass */
366 ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev));
367 ut_assert(dev == test_dev);
368
369 /* Try ping */
370 ut_assertok(test_ping(dev, 100, &pingret));
371 ut_assert(pingret == 102);
372
373 /* Now remove device 3 */
374 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);
Stefan Roese80b5bc92017-03-20 12:51:48 +0100375 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700376 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);
377
378 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
379 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);
380 ut_assertok(device_unbind(dev));
381 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
382 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);
383
Simon Glass51608c92021-12-16 20:59:32 -0700384 /* We should have one less device */
385 dm_get_stats(&dev_count, &uc_count);
386 ut_asserteq(start_dev_count, dev_count);
387 ut_asserteq(start_uc_count, uc_count);
388
Simon Glassb2c1cac2014-02-26 15:59:21 -0700389 return 0;
390}
Simon Glass1a92f832024-08-22 07:57:48 -0600391DM_TEST(dm_test_lifecycle, UTF_SCAN_PDATA | UTF_PROBE_TEST);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700392
393/* Test that we can bind/unbind and the lists update correctly */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500394static int dm_test_ordering(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700395{
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200396 struct udevice *dev, *dev_penultimate, *dev_last, *test_dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700397 int pingret;
398
Simon Glassb98bfbc2021-03-07 17:34:57 -0700399 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700400 &dev));
401 ut_assert(dev);
402
403 /* Bind two new devices (numbers 4 and 5) */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700404 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700405 &dev_penultimate));
406 ut_assert(dev_penultimate);
Simon Glassb98bfbc2021-03-07 17:34:57 -0700407 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700408 &dev_last));
409 ut_assert(dev_last);
410
411 /* Now remove device 3 */
Stefan Roese80b5bc92017-03-20 12:51:48 +0100412 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700413 ut_assertok(device_unbind(dev));
414
415 /* The device numbering should have shifted down one */
416 ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev));
417 ut_assert(dev_penultimate == test_dev);
418 ut_assertok(uclass_find_device(UCLASS_TEST, 4, &test_dev));
419 ut_assert(dev_last == test_dev);
420
421 /* Add back the original device 3, now in position 5 */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700422 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Simon Glassfef72b72014-07-23 06:55:03 -0600423 &dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700424 ut_assert(dev);
425
426 /* Try ping */
427 ut_assertok(test_ping(dev, 100, &pingret));
428 ut_assert(pingret == 102);
429
430 /* Remove 3 and 4 */
Stefan Roese80b5bc92017-03-20 12:51:48 +0100431 ut_assertok(device_remove(dev_penultimate, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700432 ut_assertok(device_unbind(dev_penultimate));
Stefan Roese80b5bc92017-03-20 12:51:48 +0100433 ut_assertok(device_remove(dev_last, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700434 ut_assertok(device_unbind(dev_last));
435
436 /* Our device should now be in position 3 */
437 ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev));
438 ut_assert(dev == test_dev);
439
440 /* Now remove device 3 */
Stefan Roese80b5bc92017-03-20 12:51:48 +0100441 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700442 ut_assertok(device_unbind(dev));
443
444 return 0;
445}
Simon Glass1a92f832024-08-22 07:57:48 -0600446DM_TEST(dm_test_ordering, UTF_SCAN_PDATA);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700447
448/* Check that we can perform operations on a device (do a ping) */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500449int dm_check_operations(struct unit_test_state *uts, struct udevice *dev,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700450 uint32_t base, struct dm_test_priv *priv)
451{
452 int expected;
453 int pingret;
454
Simon Glass71fa5b42020-12-03 16:55:18 -0700455 /* Getting the child device should allocate plat / priv */
Simon Glassb2c1cac2014-02-26 15:59:21 -0700456 ut_assertok(testfdt_ping(dev, 10, &pingret));
Simon Glass95588622020-12-22 19:30:28 -0700457 ut_assert(dev_get_priv(dev));
458 ut_assert(dev_get_plat(dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700459
460 expected = 10 + base;
461 ut_asserteq(expected, pingret);
462
463 /* Do another ping */
464 ut_assertok(testfdt_ping(dev, 20, &pingret));
465 expected = 20 + base;
466 ut_asserteq(expected, pingret);
467
468 /* Now check the ping_total */
Simon Glass95588622020-12-22 19:30:28 -0700469 priv = dev_get_priv(dev);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700470 ut_asserteq(DM_TEST_START_TOTAL + 10 + 20 + base * 2,
471 priv->ping_total);
472
473 return 0;
474}
475
476/* Check that we can perform operations on devices */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500477static int dm_test_operations(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700478{
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200479 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700480 int i;
481
482 /*
483 * Now check that the ping adds are what we expect. This is using the
484 * ping-add property in each node.
485 */
486 for (i = 0; i < ARRAY_SIZE(test_pdata); i++) {
487 uint32_t base;
488
489 ut_assertok(uclass_get_device(UCLASS_TEST, i, &dev));
490
491 /*
492 * Get the 'reg' property, which tells us what the ping add
Simon Glass71fa5b42020-12-03 16:55:18 -0700493 * should be. We don't use the plat because we want
Simon Glassb2c1cac2014-02-26 15:59:21 -0700494 * to test the code that sets that up (testfdt_drv_probe()).
495 */
496 base = test_pdata[i].ping_add;
497 debug("dev=%d, base=%d\n", i, base);
498
Simon Glass95588622020-12-22 19:30:28 -0700499 ut_assert(!dm_check_operations(uts, dev, base, dev_get_priv(dev)));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700500 }
501
502 return 0;
503}
Simon Glass1a92f832024-08-22 07:57:48 -0600504DM_TEST(dm_test_operations, UTF_SCAN_PDATA);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700505
506/* Remove all drivers and check that things work */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500507static int dm_test_remove(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700508{
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200509 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700510 int i;
511
512 for (i = 0; i < 3; i++) {
513 ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
514 ut_assert(dev);
Simon Glass6211d762020-12-19 10:40:10 -0700515 ut_assertf(dev_get_flags(dev) & DM_FLAG_ACTIVATED,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700516 "Driver %d/%s not activated", i, dev->name);
Stefan Roese80b5bc92017-03-20 12:51:48 +0100517 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glass6211d762020-12-19 10:40:10 -0700518 ut_assertf(!(dev_get_flags(dev) & DM_FLAG_ACTIVATED),
Simon Glassb2c1cac2014-02-26 15:59:21 -0700519 "Driver %d/%s should have deactivated", i,
520 dev->name);
Simon Glass95588622020-12-22 19:30:28 -0700521 ut_assert(!dev_get_priv(dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700522 }
523
524 return 0;
525}
Simon Glass1a92f832024-08-22 07:57:48 -0600526DM_TEST(dm_test_remove, UTF_SCAN_PDATA | UTF_PROBE_TEST);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700527
528/* Remove and recreate everything, check for memory leaks */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500529static int dm_test_leak(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700530{
531 int i;
532
533 for (i = 0; i < 2; i++) {
Simon Glassb2c1cac2014-02-26 15:59:21 -0700534 int ret;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700535
Joe Hershberger3a77be52015-05-20 14:27:27 -0500536 dm_leak_check_start(uts);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700537
Simon Glassb75b15b2020-12-03 16:55:23 -0700538 ut_assertok(dm_scan_plat(false));
Simon Glass5039cab2020-11-28 17:50:09 -0700539 ut_assertok(dm_scan_fdt(false));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700540
Michal Suchanek44322b52022-10-12 21:57:51 +0200541 ret = uclass_probe_all(UCLASS_TEST);
542 ut_assertok(ret);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700543
Joe Hershberger3a77be52015-05-20 14:27:27 -0500544 ut_assertok(dm_leak_check_end(uts));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700545 }
546
547 return 0;
548}
549DM_TEST(dm_test_leak, 0);
550
551/* Test uclass init/destroy methods */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500552static int dm_test_uclass(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700553{
Simon Glass51608c92021-12-16 20:59:32 -0700554 int dev_count, uc_count;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700555 struct uclass *uc;
556
Simon Glass51608c92021-12-16 20:59:32 -0700557 /* We should have just the root device and uclass */
558 dm_get_stats(&dev_count, &uc_count);
559 ut_asserteq(1, dev_count);
560 ut_asserteq(1, uc_count);
561
Simon Glassb2c1cac2014-02-26 15:59:21 -0700562 ut_assertok(uclass_get(UCLASS_TEST, &uc));
563 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
564 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
Simon Glass95588622020-12-22 19:30:28 -0700565 ut_assert(uclass_get_priv(uc));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700566
Simon Glass51608c92021-12-16 20:59:32 -0700567 dm_get_stats(&dev_count, &uc_count);
568 ut_asserteq(1, dev_count);
569 ut_asserteq(2, uc_count);
570
Simon Glassb2c1cac2014-02-26 15:59:21 -0700571 ut_assertok(uclass_destroy(uc));
572 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
573 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
574
Simon Glass51608c92021-12-16 20:59:32 -0700575 dm_get_stats(&dev_count, &uc_count);
576 ut_asserteq(1, dev_count);
577 ut_asserteq(1, uc_count);
578
Simon Glassb2c1cac2014-02-26 15:59:21 -0700579 return 0;
580}
581DM_TEST(dm_test_uclass, 0);
582
583/**
584 * create_children() - Create children of a parent node
585 *
586 * @dms: Test system state
587 * @parent: Parent device
588 * @count: Number of children to create
589 * @key: Key value to put in first child. Subsequence children
590 * receive an incrementing value
591 * @child: If not NULL, then the child device pointers are written into
592 * this array.
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100593 * Return: 0 if OK, -ve on error
Simon Glassb2c1cac2014-02-26 15:59:21 -0700594 */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500595static int create_children(struct unit_test_state *uts, struct udevice *parent,
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200596 int count, int key, struct udevice *child[])
Simon Glassb2c1cac2014-02-26 15:59:21 -0700597{
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200598 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700599 int i;
600
601 for (i = 0; i < count; i++) {
602 struct dm_test_pdata *pdata;
603
Simon Glassfef72b72014-07-23 06:55:03 -0600604 ut_assertok(device_bind_by_name(parent, false,
605 &driver_info_manual, &dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700606 pdata = calloc(1, sizeof(*pdata));
607 pdata->ping_add = key + i;
Simon Glass95588622020-12-22 19:30:28 -0700608 dev_set_plat(dev, pdata);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700609 if (child)
610 child[i] = dev;
611 }
612
613 return 0;
614}
615
616#define NODE_COUNT 10
617
Joe Hershberger3a77be52015-05-20 14:27:27 -0500618static int dm_test_children(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700619{
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200620 struct udevice *top[NODE_COUNT];
621 struct udevice *child[NODE_COUNT];
622 struct udevice *grandchild[NODE_COUNT];
623 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700624 int total;
625 int ret;
626 int i;
627
628 /* We don't care about the numbering for this test */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700629 uts->skip_post_probe = 1;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700630
631 ut_assert(NODE_COUNT > 5);
632
633 /* First create 10 top-level children */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700634 ut_assertok(create_children(uts, uts->root, NODE_COUNT, 0, top));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700635
636 /* Now a few have their own children */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500637 ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL));
638 ut_assertok(create_children(uts, top[5], NODE_COUNT, 5, child));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700639
640 /* And grandchildren */
641 for (i = 0; i < NODE_COUNT; i++)
Joe Hershberger3a77be52015-05-20 14:27:27 -0500642 ut_assertok(create_children(uts, child[i], NODE_COUNT, 50 * i,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700643 i == 2 ? grandchild : NULL));
644
645 /* Check total number of devices */
646 total = NODE_COUNT * (3 + NODE_COUNT);
647 ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_BIND]);
648
649 /* Try probing one of the grandchildren */
650 ut_assertok(uclass_get_device(UCLASS_TEST,
651 NODE_COUNT * 3 + 2 * NODE_COUNT, &dev));
652 ut_asserteq_ptr(grandchild[0], dev);
653
654 /*
655 * This should have probed the child and top node also, for a total
656 * of 3 nodes.
657 */
658 ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
659
660 /* Probe the other grandchildren */
661 for (i = 1; i < NODE_COUNT; i++)
662 ut_assertok(device_probe(grandchild[i]));
663
664 ut_asserteq(2 + NODE_COUNT, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
665
666 /* Probe everything */
Michal Suchanek44322b52022-10-12 21:57:51 +0200667 ret = uclass_probe_all(UCLASS_TEST);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700668 ut_assertok(ret);
669
670 ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
671
672 /* Remove a top-level child and check that the children are removed */
Stefan Roese80b5bc92017-03-20 12:51:48 +0100673 ut_assertok(device_remove(top[2], DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700674 ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_REMOVE]);
675 dm_testdrv_op_count[DM_TEST_OP_REMOVE] = 0;
676
677 /* Try one with grandchildren */
678 ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev));
679 ut_asserteq_ptr(dev, top[5]);
Stefan Roese80b5bc92017-03-20 12:51:48 +0100680 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700681 ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT),
682 dm_testdrv_op_count[DM_TEST_OP_REMOVE]);
683
684 /* Try the same with unbind */
685 ut_assertok(device_unbind(top[2]));
686 ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
687 dm_testdrv_op_count[DM_TEST_OP_UNBIND] = 0;
688
689 /* Try one with grandchildren */
690 ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev));
691 ut_asserteq_ptr(dev, top[6]);
692 ut_assertok(device_unbind(top[5]));
693 ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT),
694 dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
695
696 return 0;
697}
698DM_TEST(dm_test_children, 0);
Simon Glassfef72b72014-07-23 06:55:03 -0600699
Claudiu Bezneabf5b8232020-09-07 17:46:33 +0300700static int dm_test_device_reparent(struct unit_test_state *uts)
701{
Claudiu Bezneabf5b8232020-09-07 17:46:33 +0300702 struct udevice *top[NODE_COUNT];
703 struct udevice *child[NODE_COUNT];
704 struct udevice *grandchild[NODE_COUNT];
705 struct udevice *dev;
706 int total;
707 int ret;
708 int i;
709
710 /* We don't care about the numbering for this test */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700711 uts->skip_post_probe = 1;
Claudiu Bezneabf5b8232020-09-07 17:46:33 +0300712
713 ut_assert(NODE_COUNT > 5);
714
715 /* First create 10 top-level children */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700716 ut_assertok(create_children(uts, uts->root, NODE_COUNT, 0, top));
Claudiu Bezneabf5b8232020-09-07 17:46:33 +0300717
718 /* Now a few have their own children */
719 ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL));
720 ut_assertok(create_children(uts, top[5], NODE_COUNT, 5, child));
721
722 /* And grandchildren */
723 for (i = 0; i < NODE_COUNT; i++)
724 ut_assertok(create_children(uts, child[i], NODE_COUNT, 50 * i,
725 i == 2 ? grandchild : NULL));
726
727 /* Check total number of devices */
728 total = NODE_COUNT * (3 + NODE_COUNT);
729 ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_BIND]);
730
731 /* Probe everything */
732 for (i = 0; i < total; i++)
733 ut_assertok(uclass_get_device(UCLASS_TEST, i, &dev));
734
735 /* Re-parent top-level children with no grandchildren. */
736 ut_assertok(device_reparent(top[3], top[0]));
737 /* try to get devices */
738 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
739 dev;
740 ret = uclass_find_next_device(&dev)) {
741 ut_assert(!ret);
742 ut_assertnonnull(dev);
743 }
744
745 ut_assertok(device_reparent(top[4], top[0]));
746 /* try to get devices */
747 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
748 dev;
749 ret = uclass_find_next_device(&dev)) {
750 ut_assert(!ret);
751 ut_assertnonnull(dev);
752 }
753
754 /* Re-parent top-level children with grandchildren. */
755 ut_assertok(device_reparent(top[2], top[0]));
756 /* try to get devices */
757 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
758 dev;
759 ret = uclass_find_next_device(&dev)) {
760 ut_assert(!ret);
761 ut_assertnonnull(dev);
762 }
763
764 ut_assertok(device_reparent(top[5], top[2]));
765 /* try to get devices */
766 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
767 dev;
768 ret = uclass_find_next_device(&dev)) {
769 ut_assert(!ret);
770 ut_assertnonnull(dev);
771 }
772
773 /* Re-parent grandchildren. */
774 ut_assertok(device_reparent(grandchild[0], top[1]));
775 /* try to get devices */
776 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
777 dev;
778 ret = uclass_find_next_device(&dev)) {
779 ut_assert(!ret);
780 ut_assertnonnull(dev);
781 }
782
783 ut_assertok(device_reparent(grandchild[1], top[1]));
784 /* try to get devices */
785 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
786 dev;
787 ret = uclass_find_next_device(&dev)) {
788 ut_assert(!ret);
789 ut_assertnonnull(dev);
790 }
791
792 /* Remove re-pareneted devices. */
793 ut_assertok(device_remove(top[3], DM_REMOVE_NORMAL));
794 /* try to get devices */
795 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
796 dev;
797 ret = uclass_find_next_device(&dev)) {
798 ut_assert(!ret);
799 ut_assertnonnull(dev);
800 }
801
802 ut_assertok(device_remove(top[4], DM_REMOVE_NORMAL));
803 /* try to get devices */
804 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
805 dev;
806 ret = uclass_find_next_device(&dev)) {
807 ut_assert(!ret);
808 ut_assertnonnull(dev);
809 }
810
811 ut_assertok(device_remove(top[5], DM_REMOVE_NORMAL));
812 /* try to get devices */
813 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
814 dev;
815 ret = uclass_find_next_device(&dev)) {
816 ut_assert(!ret);
817 ut_assertnonnull(dev);
818 }
819
820 ut_assertok(device_remove(top[2], DM_REMOVE_NORMAL));
821 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
822 dev;
823 ret = uclass_find_next_device(&dev)) {
824 ut_assert(!ret);
825 ut_assertnonnull(dev);
826 }
827
828 ut_assertok(device_remove(grandchild[0], DM_REMOVE_NORMAL));
829 /* try to get devices */
830 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
831 dev;
832 ret = uclass_find_next_device(&dev)) {
833 ut_assert(!ret);
834 ut_assertnonnull(dev);
835 }
836
837 ut_assertok(device_remove(grandchild[1], DM_REMOVE_NORMAL));
838 /* try to get devices */
839 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
840 dev;
841 ret = uclass_find_next_device(&dev)) {
842 ut_assert(!ret);
843 ut_assertnonnull(dev);
844 }
845
846 /* Try the same with unbind */
847 ut_assertok(device_unbind(top[3]));
848 ut_assertok(device_unbind(top[4]));
849 ut_assertok(device_unbind(top[5]));
850 ut_assertok(device_unbind(top[2]));
851
852 ut_assertok(device_unbind(grandchild[0]));
853 ut_assertok(device_unbind(grandchild[1]));
854
855 return 0;
856}
857DM_TEST(dm_test_device_reparent, 0);
858
Simon Glassfef72b72014-07-23 06:55:03 -0600859/* Test that pre-relocation devices work as expected */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500860static int dm_test_pre_reloc(struct unit_test_state *uts)
Simon Glassfef72b72014-07-23 06:55:03 -0600861{
862 struct udevice *dev;
863
864 /* The normal driver should refuse to bind before relocation */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700865 ut_asserteq(-EPERM, device_bind_by_name(uts->root, true,
Simon Glassfef72b72014-07-23 06:55:03 -0600866 &driver_info_manual, &dev));
867
868 /* But this one is marked pre-reloc */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700869 ut_assertok(device_bind_by_name(uts->root, true,
Simon Glassfef72b72014-07-23 06:55:03 -0600870 &driver_info_pre_reloc, &dev));
871
872 return 0;
873}
874DM_TEST(dm_test_pre_reloc, 0);
Simon Glassde708672014-07-23 06:55:15 -0600875
Stefan Roeseeaffda72017-03-27 11:02:43 +0200876/*
877 * Test that removal of devices, either via the "normal" device_remove()
878 * API or via the device driver selective flag works as expected
879 */
880static int dm_test_remove_active_dma(struct unit_test_state *uts)
881{
Stefan Roeseeaffda72017-03-27 11:02:43 +0200882 struct udevice *dev;
883
Simon Glassb98bfbc2021-03-07 17:34:57 -0700884 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_act_dma,
Stefan Roeseeaffda72017-03-27 11:02:43 +0200885 &dev));
886 ut_assert(dev);
887
888 /* Probe the device */
889 ut_assertok(device_probe(dev));
890
891 /* Test if device is active right now */
892 ut_asserteq(true, device_active(dev));
893
894 /* Remove the device via selective remove flag */
895 dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
896
897 /* Test if device is inactive right now */
898 ut_asserteq(false, device_active(dev));
899
900 /* Probe the device again */
901 ut_assertok(device_probe(dev));
902
903 /* Test if device is active right now */
904 ut_asserteq(true, device_active(dev));
905
906 /* Remove the device via "normal" remove API */
907 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
908
909 /* Test if device is inactive right now */
910 ut_asserteq(false, device_active(dev));
911
912 /*
913 * Test if a device without the active DMA flags is not removed upon
914 * the active DMA remove call
915 */
916 ut_assertok(device_unbind(dev));
Simon Glassb98bfbc2021-03-07 17:34:57 -0700917 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Stefan Roeseeaffda72017-03-27 11:02:43 +0200918 &dev));
919 ut_assert(dev);
920
921 /* Probe the device */
922 ut_assertok(device_probe(dev));
923
924 /* Test if device is active right now */
925 ut_asserteq(true, device_active(dev));
926
927 /* Remove the device via selective remove flag */
928 dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
929
930 /* Test if device is still active right now */
931 ut_asserteq(true, device_active(dev));
932
933 return 0;
934}
935DM_TEST(dm_test_remove_active_dma, 0);
936
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700937/* Test removal of 'vital' devices */
938static int dm_test_remove_vital(struct unit_test_state *uts)
939{
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700940 struct udevice *normal, *dma, *vital, *dma_vital;
941
942 /* Skip the behaviour in test_post_probe() */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700943 uts->skip_post_probe = 1;
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700944
Simon Glassb98bfbc2021-03-07 17:34:57 -0700945 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700946 &normal));
947 ut_assertnonnull(normal);
948
Simon Glassb98bfbc2021-03-07 17:34:57 -0700949 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_act_dma,
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700950 &dma));
951 ut_assertnonnull(dma);
952
Simon Glassb98bfbc2021-03-07 17:34:57 -0700953 ut_assertok(device_bind_by_name(uts->root, false,
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700954 &driver_info_vital_clk, &vital));
955 ut_assertnonnull(vital);
956
Simon Glassb98bfbc2021-03-07 17:34:57 -0700957 ut_assertok(device_bind_by_name(uts->root, false,
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700958 &driver_info_act_dma_vital_clk,
959 &dma_vital));
960 ut_assertnonnull(dma_vital);
961
962 /* Probe the devices */
963 ut_assertok(device_probe(normal));
964 ut_assertok(device_probe(dma));
965 ut_assertok(device_probe(vital));
966 ut_assertok(device_probe(dma_vital));
967
968 /* Check that devices are active right now */
969 ut_asserteq(true, device_active(normal));
970 ut_asserteq(true, device_active(dma));
971 ut_asserteq(true, device_active(vital));
972 ut_asserteq(true, device_active(dma_vital));
973
974 /* Remove active devices via selective remove flag */
975 dm_remove_devices_flags(DM_REMOVE_NON_VITAL | DM_REMOVE_ACTIVE_ALL);
976
977 /*
978 * Check that this only has an effect on the dma device, since two
979 * devices are vital and the third does not have active DMA
980 */
981 ut_asserteq(true, device_active(normal));
982 ut_asserteq(false, device_active(dma));
983 ut_asserteq(true, device_active(vital));
984 ut_asserteq(true, device_active(dma_vital));
985
986 /* Remove active devices via selective remove flag */
987 ut_assertok(device_probe(dma));
988 dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
989
990 /* This should have affected both active-dma devices */
991 ut_asserteq(true, device_active(normal));
992 ut_asserteq(false, device_active(dma));
993 ut_asserteq(true, device_active(vital));
994 ut_asserteq(false, device_active(dma_vital));
995
996 /* Remove non-vital devices */
997 ut_assertok(device_probe(dma));
998 ut_assertok(device_probe(dma_vital));
999 dm_remove_devices_flags(DM_REMOVE_NON_VITAL);
1000
1001 /* This should have affected only non-vital devices */
1002 ut_asserteq(false, device_active(normal));
1003 ut_asserteq(false, device_active(dma));
1004 ut_asserteq(true, device_active(vital));
1005 ut_asserteq(true, device_active(dma_vital));
1006
1007 /* Remove vital devices via normal remove flag */
1008 ut_assertok(device_probe(normal));
1009 ut_assertok(device_probe(dma));
1010 dm_remove_devices_flags(DM_REMOVE_NORMAL);
1011
1012 /* Check that all devices are inactive right now */
1013 ut_asserteq(false, device_active(normal));
1014 ut_asserteq(false, device_active(dma));
1015 ut_asserteq(false, device_active(vital));
1016 ut_asserteq(false, device_active(dma_vital));
1017
1018 return 0;
1019}
1020DM_TEST(dm_test_remove_vital, 0);
1021
Janne Grunau64609732024-11-23 22:44:05 +01001022/* Test removal of 'active' devices */
1023static int dm_test_remove_active(struct unit_test_state *uts)
1024{
1025 struct udevice *normal, *dma, *vital, *dma_vital;
1026
1027 /* Skip the behaviour in test_post_probe() */
1028 uts->skip_post_probe = 1;
1029
1030 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
1031 &normal));
1032 ut_assertnonnull(normal);
1033
1034 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_act_dma,
1035 &dma));
1036 ut_assertnonnull(dma);
1037
1038 ut_assertok(device_bind_by_name(uts->root, false,
1039 &driver_info_vital_clk, &vital));
1040 ut_assertnonnull(vital);
1041
1042 ut_assertok(device_bind_by_name(uts->root, false,
1043 &driver_info_act_dma_vital_clk,
1044 &dma_vital));
1045 ut_assertnonnull(dma_vital);
1046
1047 /* Probe the devices */
1048 ut_assertok(device_probe(normal));
1049 ut_assertok(device_probe(dma));
1050 ut_assertok(device_probe(vital));
1051 ut_assertok(device_probe(dma_vital));
1052
1053 /* Check that devices are active right now */
1054 ut_asserteq(true, device_active(normal));
1055 ut_asserteq(true, device_active(dma));
1056 ut_asserteq(true, device_active(vital));
1057 ut_asserteq(true, device_active(dma_vital));
1058
1059 /* Remove active devices in an ordered way */
1060 dm_remove_devices_active();
1061
1062 /* Check that all devices are inactive right now */
1063 ut_asserteq(true, device_active(normal));
1064 ut_asserteq(false, device_active(dma));
1065 ut_asserteq(true, device_active(vital));
1066 ut_asserteq(false, device_active(dma_vital));
1067
1068 return 0;
1069}
1070DM_TEST(dm_test_remove_active, 0);
1071
Joe Hershberger3a77be52015-05-20 14:27:27 -05001072static int dm_test_uclass_before_ready(struct unit_test_state *uts)
Simon Glassde708672014-07-23 06:55:15 -06001073{
1074 struct uclass *uc;
1075
1076 ut_assertok(uclass_get(UCLASS_TEST, &uc));
1077
Simon Glass51a0eac2015-04-19 07:21:02 -06001078 gd->dm_root = NULL;
Simon Glass51a0eac2015-04-19 07:21:02 -06001079 memset(&gd->uclass_root, '\0', sizeof(gd->uclass_root));
1080
Simon Glassde708672014-07-23 06:55:15 -06001081 ut_asserteq_ptr(NULL, uclass_find(UCLASS_TEST));
Simon Glass8e9eacf2021-08-01 12:05:23 -06001082 ut_asserteq(-EDEADLK, uclass_get(UCLASS_TEST, &uc));
Simon Glassde708672014-07-23 06:55:15 -06001083
1084 return 0;
1085}
Simon Glassde708672014-07-23 06:55:15 -06001086DM_TEST(dm_test_uclass_before_ready, 0);
Simon Glass98fd5d12015-01-25 08:27:04 -07001087
Joe Hershberger3a77be52015-05-20 14:27:27 -05001088static int dm_test_uclass_devices_find(struct unit_test_state *uts)
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001089{
1090 struct udevice *dev;
1091 int ret;
1092
1093 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
1094 dev;
1095 ret = uclass_find_next_device(&dev)) {
1096 ut_assert(!ret);
Heinrich Schuchardt6c2a8712020-07-17 00:20:14 +02001097 ut_assertnonnull(dev);
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001098 }
1099
Simon Glass0bb44272019-09-25 08:55:55 -06001100 ut_assertok(uclass_find_first_device(UCLASS_TEST_DUMMY, &dev));
Heinrich Schuchardt6c2a8712020-07-17 00:20:14 +02001101 ut_assertnull(dev);
Marcel Ziswiler75ec16f2019-02-01 16:01:07 +01001102
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001103 return 0;
1104}
Simon Glass1a92f832024-08-22 07:57:48 -06001105DM_TEST(dm_test_uclass_devices_find, UTF_SCAN_PDATA);
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001106
Joe Hershberger3a77be52015-05-20 14:27:27 -05001107static int dm_test_uclass_devices_find_by_name(struct unit_test_state *uts)
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001108{
1109 struct udevice *finddev;
1110 struct udevice *testdev;
1111 int findret, ret;
1112
1113 /*
1114 * For each test device found in fdt like: "a-test", "b-test", etc.,
1115 * use its name and try to find it by uclass_find_device_by_name().
1116 * Then, on success check if:
1117 * - current 'testdev' name is equal to the returned 'finddev' name
1118 * - current 'testdev' pointer is equal to the returned 'finddev'
1119 *
1120 * We assume that, each uclass's device name is unique, so if not, then
1121 * this will fail on checking condition: testdev == finddev, since the
1122 * uclass_find_device_by_name(), returns the first device by given name.
1123 */
1124 for (ret = uclass_find_first_device(UCLASS_TEST_FDT, &testdev);
1125 testdev;
1126 ret = uclass_find_next_device(&testdev)) {
1127 ut_assertok(ret);
Heinrich Schuchardt6c2a8712020-07-17 00:20:14 +02001128 ut_assertnonnull(testdev);
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001129
1130 findret = uclass_find_device_by_name(UCLASS_TEST_FDT,
1131 testdev->name,
1132 &finddev);
1133
1134 ut_assertok(findret);
1135 ut_assert(testdev);
1136 ut_asserteq_str(testdev->name, finddev->name);
1137 ut_asserteq_ptr(testdev, finddev);
1138 }
1139
1140 return 0;
1141}
Simon Glass1a92f832024-08-22 07:57:48 -06001142DM_TEST(dm_test_uclass_devices_find_by_name, UTF_SCAN_FDT);
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001143
Joe Hershberger3a77be52015-05-20 14:27:27 -05001144static int dm_test_uclass_devices_get(struct unit_test_state *uts)
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001145{
1146 struct udevice *dev;
1147 int ret;
1148
Michal Suchanek98e1ada2022-10-12 21:58:09 +02001149 for (ret = uclass_first_device_check(UCLASS_TEST, &dev);
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001150 dev;
Michal Suchanek98e1ada2022-10-12 21:58:09 +02001151 ret = uclass_next_device_check(&dev)) {
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001152 ut_assert(!ret);
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001153 ut_assert(device_active(dev));
1154 }
1155
1156 return 0;
1157}
Simon Glass1a92f832024-08-22 07:57:48 -06001158DM_TEST(dm_test_uclass_devices_get, UTF_SCAN_PDATA);
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001159
Joe Hershberger3a77be52015-05-20 14:27:27 -05001160static int dm_test_uclass_devices_get_by_name(struct unit_test_state *uts)
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001161{
1162 struct udevice *finddev;
1163 struct udevice *testdev;
1164 int ret, findret;
1165
1166 /*
1167 * For each test device found in fdt like: "a-test", "b-test", etc.,
1168 * use its name and try to get it by uclass_get_device_by_name().
1169 * On success check if:
1170 * - returned finddev' is active
1171 * - current 'testdev' name is equal to the returned 'finddev' name
1172 * - current 'testdev' pointer is equal to the returned 'finddev'
1173 *
1174 * We asserts that the 'testdev' is active on each loop entry, so we
1175 * could be sure that the 'finddev' is activated too, but for sure
1176 * we check it again.
1177 *
1178 * We assume that, each uclass's device name is unique, so if not, then
1179 * this will fail on checking condition: testdev == finddev, since the
1180 * uclass_get_device_by_name(), returns the first device by given name.
1181 */
Michal Suchanek98e1ada2022-10-12 21:58:09 +02001182 for (ret = uclass_first_device_check(UCLASS_TEST_FDT, &testdev);
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001183 testdev;
Michal Suchanek98e1ada2022-10-12 21:58:09 +02001184 ret = uclass_next_device_check(&testdev)) {
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001185 ut_assertok(ret);
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001186 ut_assert(device_active(testdev));
1187
1188 findret = uclass_get_device_by_name(UCLASS_TEST_FDT,
1189 testdev->name,
1190 &finddev);
1191
1192 ut_assertok(findret);
1193 ut_assert(finddev);
1194 ut_assert(device_active(finddev));
1195 ut_asserteq_str(testdev->name, finddev->name);
1196 ut_asserteq_ptr(testdev, finddev);
1197 }
1198
1199 return 0;
1200}
Simon Glass1a92f832024-08-22 07:57:48 -06001201DM_TEST(dm_test_uclass_devices_get_by_name, UTF_SCAN_FDT);
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001202
Joe Hershberger3a77be52015-05-20 14:27:27 -05001203static int dm_test_device_get_uclass_id(struct unit_test_state *uts)
Simon Glass98fd5d12015-01-25 08:27:04 -07001204{
1205 struct udevice *dev;
1206
1207 ut_assertok(uclass_get_device(UCLASS_TEST, 0, &dev));
1208 ut_asserteq(UCLASS_TEST, device_get_uclass_id(dev));
1209
1210 return 0;
1211}
Simon Glass1a92f832024-08-22 07:57:48 -06001212DM_TEST(dm_test_device_get_uclass_id, UTF_SCAN_PDATA);
Simon Glass70e35b42017-12-28 13:14:15 -07001213
1214static int dm_test_uclass_names(struct unit_test_state *uts)
1215{
1216 ut_asserteq_str("test", uclass_get_name(UCLASS_TEST));
1217 ut_asserteq(UCLASS_TEST, uclass_get_by_name("test"));
1218
Simon Glassf1f519f2022-04-24 23:30:59 -06001219 ut_asserteq(UCLASS_SPI, uclass_get_by_name("spi"));
1220
Simon Glass70e35b42017-12-28 13:14:15 -07001221 return 0;
1222}
Simon Glass1a92f832024-08-22 07:57:48 -06001223DM_TEST(dm_test_uclass_names, UTF_SCAN_PDATA);
Simon Glassb775e872018-10-01 12:22:07 -06001224
1225static int dm_test_inactive_child(struct unit_test_state *uts)
1226{
Simon Glassb775e872018-10-01 12:22:07 -06001227 struct udevice *parent, *dev1, *dev2;
1228
1229 /* Skip the behaviour in test_post_probe() */
Simon Glassb98bfbc2021-03-07 17:34:57 -07001230 uts->skip_post_probe = 1;
Simon Glassb775e872018-10-01 12:22:07 -06001231
1232 ut_assertok(uclass_first_device_err(UCLASS_TEST, &parent));
1233
1234 /*
1235 * Create a child but do not activate it. Calling the function again
1236 * should return the same child.
1237 */
1238 ut_asserteq(-ENODEV, device_find_first_inactive_child(parent,
1239 UCLASS_TEST, &dev1));
Simon Glass65130cd2020-12-28 20:34:56 -07001240 ut_assertok(device_bind(parent, DM_DRIVER_GET(test_drv),
Simon Glass884870f2020-11-28 17:50:01 -07001241 "test_child", 0, ofnode_null(), &dev1));
Simon Glassb775e872018-10-01 12:22:07 -06001242
1243 ut_assertok(device_find_first_inactive_child(parent, UCLASS_TEST,
1244 &dev2));
1245 ut_asserteq_ptr(dev1, dev2);
1246
1247 ut_assertok(device_probe(dev1));
1248 ut_asserteq(-ENODEV, device_find_first_inactive_child(parent,
1249 UCLASS_TEST, &dev2));
1250
1251 return 0;
1252}
Simon Glass1a92f832024-08-22 07:57:48 -06001253DM_TEST(dm_test_inactive_child, UTF_SCAN_PDATA);
Simon Glass6a109b32020-12-16 21:20:10 -07001254
1255/* Make sure all bound devices have a sequence number */
1256static int dm_test_all_have_seq(struct unit_test_state *uts)
1257{
1258 struct udevice *dev;
1259 struct uclass *uc;
1260
Simon Glass784cd9e2020-12-19 10:40:17 -07001261 list_for_each_entry(uc, gd->uclass_root, sibling_node) {
Simon Glass6a109b32020-12-16 21:20:10 -07001262 list_for_each_entry(dev, &uc->dev_head, uclass_node) {
Simon Glass5e349922020-12-19 10:40:09 -07001263 if (dev->seq_ == -1)
Simon Glass6a109b32020-12-16 21:20:10 -07001264 printf("Device '%s' has no seq (%d)\n",
Simon Glass5e349922020-12-19 10:40:09 -07001265 dev->name, dev->seq_);
1266 ut_assert(dev->seq_ != -1);
Simon Glass6a109b32020-12-16 21:20:10 -07001267 }
1268 }
1269
1270 return 0;
1271}
Simon Glass1a92f832024-08-22 07:57:48 -06001272DM_TEST(dm_test_all_have_seq, UTF_SCAN_PDATA);
Nicolas Saenz Julienne892e9b42021-01-12 13:55:25 +01001273
Simon Glass26974252021-07-05 16:32:42 -06001274#if CONFIG_IS_ENABLED(DM_DMA)
Nicolas Saenz Julienne892e9b42021-01-12 13:55:25 +01001275static int dm_test_dma_offset(struct unit_test_state *uts)
1276{
1277 struct udevice *dev;
1278 ofnode node;
1279
1280 /* Make sure the bus's dma-ranges aren't taken into account here */
1281 node = ofnode_path("/mmio-bus@0");
1282 ut_assert(ofnode_valid(node));
1283 ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, &dev));
1284 ut_asserteq_64(0, dev->dma_offset);
1285
1286 /* Device behind a bus with dma-ranges */
1287 node = ofnode_path("/mmio-bus@0/subnode@0");
1288 ut_assert(ofnode_valid(node));
1289 ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, &dev));
1290 ut_asserteq_64(-0x10000000ULL, dev->dma_offset);
1291
1292 /* This one has no dma-ranges */
1293 node = ofnode_path("/mmio-bus@1");
1294 ut_assert(ofnode_valid(node));
1295 ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, &dev));
1296 node = ofnode_path("/mmio-bus@1/subnode@0");
1297 ut_assert(ofnode_valid(node));
1298 ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, &dev));
1299 ut_asserteq_64(0, dev->dma_offset);
1300
1301 return 0;
1302}
Simon Glass1a92f832024-08-22 07:57:48 -06001303DM_TEST(dm_test_dma_offset, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass26974252021-07-05 16:32:42 -06001304#endif
Simon Glass51608c92021-12-16 20:59:32 -07001305
1306/* Test dm_get_stats() */
1307static int dm_test_get_stats(struct unit_test_state *uts)
1308{
1309 int dev_count, uc_count;
1310
1311 dm_get_stats(&dev_count, &uc_count);
1312 ut_assert(dev_count > 50);
1313 ut_assert(uc_count > 30);
1314
1315 return 0;
1316}
Simon Glass1a92f832024-08-22 07:57:48 -06001317DM_TEST(dm_test_get_stats, UTF_SCAN_FDT);
Simon Glass9670f7d2022-04-24 23:31:00 -06001318
1319/* Test uclass_find_device_by_name() */
1320static int dm_test_uclass_find_device(struct unit_test_state *uts)
1321{
1322 struct udevice *dev;
1323
1324 ut_assertok(uclass_find_device_by_name(UCLASS_I2C, "i2c@0", &dev));
1325 ut_asserteq(-ENODEV,
1326 uclass_find_device_by_name(UCLASS_I2C, "i2c@0x", &dev));
1327 ut_assertok(uclass_find_device_by_namelen(UCLASS_I2C, "i2c@0x", 5,
1328 &dev));
1329
1330 return 0;
1331}
Simon Glass1a92f832024-08-22 07:57:48 -06001332DM_TEST(dm_test_uclass_find_device, UTF_SCAN_FDT);
Simon Glassd1f12cf2022-05-08 04:39:24 -06001333
1334/* Test getting information about tags attached to devices */
1335static int dm_test_dev_get_attach(struct unit_test_state *uts)
1336{
1337 struct udevice *dev;
1338
1339 ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev));
1340 ut_asserteq_str("a-test", dev->name);
1341
1342 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PLAT));
1343 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PRIV));
1344 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_UC_PRIV));
1345 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_UC_PLAT));
1346 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PLAT));
1347 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PRIV));
1348
1349 ut_asserteq(sizeof(struct dm_test_pdata),
1350 dev_get_attach_size(dev, DM_TAG_PLAT));
1351 ut_asserteq(sizeof(struct dm_test_priv),
1352 dev_get_attach_size(dev, DM_TAG_PRIV));
1353 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_UC_PRIV));
1354 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_UC_PLAT));
1355 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PLAT));
1356 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PRIV));
1357
1358 return 0;
1359}
Simon Glass1a92f832024-08-22 07:57:48 -06001360DM_TEST(dm_test_dev_get_attach, UTF_SCAN_FDT);
Simon Glassd1f12cf2022-05-08 04:39:24 -06001361
1362/* Test getting information about tags attached to bus devices */
1363static int dm_test_dev_get_attach_bus(struct unit_test_state *uts)
1364{
1365 struct udevice *dev, *child;
1366
1367 ut_assertok(uclass_first_device_err(UCLASS_TEST_BUS, &dev));
1368 ut_asserteq_str("some-bus", dev->name);
1369
1370 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PLAT));
1371 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PRIV));
1372 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_UC_PRIV));
1373 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_UC_PLAT));
1374 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PLAT));
1375 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PRIV));
1376
1377 ut_asserteq(sizeof(struct dm_test_pdata),
1378 dev_get_attach_size(dev, DM_TAG_PLAT));
1379 ut_asserteq(sizeof(struct dm_test_priv),
1380 dev_get_attach_size(dev, DM_TAG_PRIV));
1381 ut_asserteq(sizeof(struct dm_test_uclass_priv),
1382 dev_get_attach_size(dev, DM_TAG_UC_PRIV));
1383 ut_asserteq(sizeof(struct dm_test_uclass_plat),
1384 dev_get_attach_size(dev, DM_TAG_UC_PLAT));
1385 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PLAT));
1386 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PRIV));
1387
1388 /* Now try the child of the bus */
1389 ut_assertok(device_first_child_err(dev, &child));
1390 ut_asserteq_str("c-test@5", child->name);
1391
1392 ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PLAT));
1393 ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PRIV));
1394 ut_assertnull(dev_get_attach_ptr(child, DM_TAG_UC_PRIV));
1395 ut_assertnull(dev_get_attach_ptr(child, DM_TAG_UC_PLAT));
1396 ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PARENT_PLAT));
1397 ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PARENT_PRIV));
1398
1399 ut_asserteq(sizeof(struct dm_test_pdata),
1400 dev_get_attach_size(child, DM_TAG_PLAT));
1401 ut_asserteq(sizeof(struct dm_test_priv),
1402 dev_get_attach_size(child, DM_TAG_PRIV));
1403 ut_asserteq(0, dev_get_attach_size(child, DM_TAG_UC_PRIV));
1404 ut_asserteq(0, dev_get_attach_size(child, DM_TAG_UC_PLAT));
1405 ut_asserteq(sizeof(struct dm_test_parent_plat),
1406 dev_get_attach_size(child, DM_TAG_PARENT_PLAT));
1407 ut_asserteq(sizeof(struct dm_test_parent_data),
1408 dev_get_attach_size(child, DM_TAG_PARENT_PRIV));
1409
1410 return 0;
1411}
Simon Glass1a92f832024-08-22 07:57:48 -06001412DM_TEST(dm_test_dev_get_attach_bus, UTF_SCAN_FDT);
Simon Glassbe1621b2022-05-08 04:39:25 -06001413
1414/* Test getting information about tags attached to bus devices */
1415static int dm_test_dev_get_mem(struct unit_test_state *uts)
1416{
1417 struct dm_stats stats;
1418
1419 dm_get_mem(&stats);
1420
1421 return 0;
1422}
Simon Glass1a92f832024-08-22 07:57:48 -06001423DM_TEST(dm_test_dev_get_mem, UTF_SCAN_FDT);
Simon Glassf66139f2024-10-19 09:21:49 -06001424
1425/* Test uclass_try_first_device() */
1426static int dm_test_try_first_device(struct unit_test_state *uts)
1427{
1428 struct udevice *dev;
1429
1430 /* Check that it doesn't create a device or uclass */
1431 ut_assertnull(uclass_find(UCLASS_TEST));
1432 ut_assertnull(uclass_try_first_device(UCLASS_TEST));
1433 ut_assertnull(uclass_try_first_device(UCLASS_TEST));
1434 ut_assertnull(uclass_find(UCLASS_TEST));
1435
1436 /* Create a test device */
1437 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
1438 &dev));
1439 dev = uclass_try_first_device(UCLASS_TEST);
1440 ut_assertnonnull(dev);
1441 ut_asserteq(UCLASS_TEST, device_get_uclass_id(dev));
1442
1443 return 0;
1444}
1445DM_TEST(dm_test_try_first_device, 0);