blob: e0c5b9e0017c760dc800253ab4e9edd93a688101 [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
189 return 0;
190}
Simon Glass1a92f832024-08-22 07:57:48 -0600191DM_TEST(dm_test_compare_node_name, UTF_SCAN_PDATA);
Kishon Vijay Abraham Iae93e8a2021-07-21 21:28:31 +0530192
Simon Glass71fa5b42020-12-03 16:55:18 -0700193/* Test that binding with uclass plat setting occurs correctly */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500194static int dm_test_autobind_uclass_pdata_valid(struct unit_test_state *uts)
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200195{
196 struct dm_test_perdev_uc_pdata *uc_pdata;
197 struct udevice *dev;
198
199 /**
200 * In the test_postbind() method of test uclass driver, the uclass
201 * platform data should be set to three test int values - test it.
202 */
203 for (uclass_find_first_device(UCLASS_TEST, &dev);
204 dev;
205 uclass_find_next_device(&dev)) {
Heinrich Schuchardt6c2a8712020-07-17 00:20:14 +0200206 ut_assertnonnull(dev);
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200207
Simon Glass71fa5b42020-12-03 16:55:18 -0700208 uc_pdata = dev_get_uclass_plat(dev);
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200209 ut_assert(uc_pdata);
210 ut_assert(uc_pdata->intval1 == TEST_UC_PDATA_INTVAL1);
211 ut_assert(uc_pdata->intval2 == TEST_UC_PDATA_INTVAL2);
212 ut_assert(uc_pdata->intval3 == TEST_UC_PDATA_INTVAL3);
213 }
214
215 return 0;
216}
Simon Glass1a92f832024-08-22 07:57:48 -0600217DM_TEST(dm_test_autobind_uclass_pdata_valid, UTF_SCAN_PDATA);
Przemyslaw Marczak34cbe312015-04-15 13:07:19 +0200218
Simon Glassb2c1cac2014-02-26 15:59:21 -0700219/* Test that autoprobe finds all the expected devices */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500220static int dm_test_autoprobe(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700221{
222 int expected_base_add;
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200223 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700224 struct uclass *uc;
225 int i;
226
227 ut_assertok(uclass_get(UCLASS_TEST, &uc));
228 ut_assert(uc);
229
230 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
Simon Glass9c1f3822015-03-05 12:25:22 -0700231 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700232 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
233
234 /* The root device should not be activated until needed */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700235 ut_assert(dev_get_flags(uts->root) & DM_FLAG_ACTIVATED);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700236
237 /*
238 * We should be able to find the three test devices, and they should
239 * all be activated as they are used (lazy activation, required by
240 * U-Boot)
241 */
242 for (i = 0; i < 3; i++) {
243 ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
244 ut_assert(dev);
Simon Glass6211d762020-12-19 10:40:10 -0700245 ut_assertf(!(dev_get_flags(dev) & DM_FLAG_ACTIVATED),
Simon Glassb2c1cac2014-02-26 15:59:21 -0700246 "Driver %d/%s already activated", i, dev->name);
247
248 /* This should activate it */
249 ut_assertok(uclass_get_device(UCLASS_TEST, i, &dev));
250 ut_assert(dev);
Simon Glass6211d762020-12-19 10:40:10 -0700251 ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700252
253 /* Activating a device should activate the root device */
254 if (!i)
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
Simon Glass9c1f3822015-03-05 12:25:22 -0700258 /*
259 * Our 3 dm_test_info children should be passed to pre_probe and
260 * post_probe
261 */
Simon Glassb2c1cac2014-02-26 15:59:21 -0700262 ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
Simon Glass9c1f3822015-03-05 12:25:22 -0700263 ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700264
265 /* Also we can check the per-device data */
266 expected_base_add = 0;
267 for (i = 0; i < 3; i++) {
268 struct dm_test_uclass_perdev_priv *priv;
269 struct dm_test_pdata *pdata;
270
271 ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
272 ut_assert(dev);
273
Simon Glassde0977b2015-03-05 12:25:20 -0700274 priv = dev_get_uclass_priv(dev);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700275 ut_assert(priv);
276 ut_asserteq(expected_base_add, priv->base_add);
277
Simon Glass95588622020-12-22 19:30:28 -0700278 pdata = dev_get_plat(dev);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700279 expected_base_add += pdata->ping_add;
280 }
281
282 return 0;
283}
Simon Glass1a92f832024-08-22 07:57:48 -0600284DM_TEST(dm_test_autoprobe, UTF_SCAN_PDATA);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700285
Simon Glass71fa5b42020-12-03 16:55:18 -0700286/* Check that we see the correct plat in each device */
Simon Glassb75b15b2020-12-03 16:55:23 -0700287static int dm_test_plat(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700288{
289 const struct dm_test_pdata *pdata;
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200290 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700291 int i;
292
293 for (i = 0; i < 3; i++) {
294 ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
295 ut_assert(dev);
Simon Glass95588622020-12-22 19:30:28 -0700296 pdata = dev_get_plat(dev);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700297 ut_assert(pdata->ping_add == test_pdata[i].ping_add);
298 }
299
300 return 0;
301}
Simon Glass1a92f832024-08-22 07:57:48 -0600302DM_TEST(dm_test_plat, UTF_SCAN_PDATA);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700303
304/* Test that we can bind, probe, remove, unbind a driver */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500305static int dm_test_lifecycle(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700306{
307 int op_count[DM_TEST_OP_COUNT];
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200308 struct udevice *dev, *test_dev;
Simon Glass51608c92021-12-16 20:59:32 -0700309 int start_dev_count, start_uc_count;
310 int dev_count, uc_count;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700311 int pingret;
312 int ret;
313
314 memcpy(op_count, dm_testdrv_op_count, sizeof(op_count));
315
Simon Glass51608c92021-12-16 20:59:32 -0700316 dm_get_stats(&start_dev_count, &start_uc_count);
317
Simon Glassb98bfbc2021-03-07 17:34:57 -0700318 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700319 &dev));
320 ut_assert(dev);
321 ut_assert(dm_testdrv_op_count[DM_TEST_OP_BIND]
322 == op_count[DM_TEST_OP_BIND] + 1);
Simon Glass95588622020-12-22 19:30:28 -0700323 ut_assert(!dev_get_priv(dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700324
Simon Glass51608c92021-12-16 20:59:32 -0700325 /* We should have one more device */
326 dm_get_stats(&dev_count, &uc_count);
327 ut_asserteq(start_dev_count + 1, dev_count);
328 ut_asserteq(start_uc_count, uc_count);
329
Simon Glassb2c1cac2014-02-26 15:59:21 -0700330 /* Probe the device - it should fail allocating private data */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700331 uts->force_fail_alloc = 1;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700332 ret = device_probe(dev);
333 ut_assert(ret == -ENOMEM);
334 ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE]
335 == op_count[DM_TEST_OP_PROBE] + 1);
Simon Glass95588622020-12-22 19:30:28 -0700336 ut_assert(!dev_get_priv(dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700337
338 /* Try again without the alloc failure */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700339 uts->force_fail_alloc = 0;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700340 ut_assertok(device_probe(dev));
341 ut_assert(dm_testdrv_op_count[DM_TEST_OP_PROBE]
342 == op_count[DM_TEST_OP_PROBE] + 2);
Simon Glass95588622020-12-22 19:30:28 -0700343 ut_assert(dev_get_priv(dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700344
345 /* This should be device 3 in the uclass */
346 ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev));
347 ut_assert(dev == test_dev);
348
349 /* Try ping */
350 ut_assertok(test_ping(dev, 100, &pingret));
351 ut_assert(pingret == 102);
352
353 /* Now remove device 3 */
354 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);
Stefan Roese80b5bc92017-03-20 12:51:48 +0100355 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700356 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_REMOVE]);
357
358 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
359 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);
360 ut_assertok(device_unbind(dev));
361 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
362 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);
363
Simon Glass51608c92021-12-16 20:59:32 -0700364 /* We should have one less device */
365 dm_get_stats(&dev_count, &uc_count);
366 ut_asserteq(start_dev_count, dev_count);
367 ut_asserteq(start_uc_count, uc_count);
368
Simon Glassb2c1cac2014-02-26 15:59:21 -0700369 return 0;
370}
Simon Glass1a92f832024-08-22 07:57:48 -0600371DM_TEST(dm_test_lifecycle, UTF_SCAN_PDATA | UTF_PROBE_TEST);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700372
373/* Test that we can bind/unbind and the lists update correctly */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500374static int dm_test_ordering(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700375{
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200376 struct udevice *dev, *dev_penultimate, *dev_last, *test_dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700377 int pingret;
378
Simon Glassb98bfbc2021-03-07 17:34:57 -0700379 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700380 &dev));
381 ut_assert(dev);
382
383 /* Bind two new devices (numbers 4 and 5) */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700384 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700385 &dev_penultimate));
386 ut_assert(dev_penultimate);
Simon Glassb98bfbc2021-03-07 17:34:57 -0700387 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700388 &dev_last));
389 ut_assert(dev_last);
390
391 /* Now remove device 3 */
Stefan Roese80b5bc92017-03-20 12:51:48 +0100392 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700393 ut_assertok(device_unbind(dev));
394
395 /* The device numbering should have shifted down one */
396 ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev));
397 ut_assert(dev_penultimate == test_dev);
398 ut_assertok(uclass_find_device(UCLASS_TEST, 4, &test_dev));
399 ut_assert(dev_last == test_dev);
400
401 /* Add back the original device 3, now in position 5 */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700402 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Simon Glassfef72b72014-07-23 06:55:03 -0600403 &dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700404 ut_assert(dev);
405
406 /* Try ping */
407 ut_assertok(test_ping(dev, 100, &pingret));
408 ut_assert(pingret == 102);
409
410 /* Remove 3 and 4 */
Stefan Roese80b5bc92017-03-20 12:51:48 +0100411 ut_assertok(device_remove(dev_penultimate, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700412 ut_assertok(device_unbind(dev_penultimate));
Stefan Roese80b5bc92017-03-20 12:51:48 +0100413 ut_assertok(device_remove(dev_last, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700414 ut_assertok(device_unbind(dev_last));
415
416 /* Our device should now be in position 3 */
417 ut_assertok(uclass_find_device(UCLASS_TEST, 3, &test_dev));
418 ut_assert(dev == test_dev);
419
420 /* Now remove device 3 */
Stefan Roese80b5bc92017-03-20 12:51:48 +0100421 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700422 ut_assertok(device_unbind(dev));
423
424 return 0;
425}
Simon Glass1a92f832024-08-22 07:57:48 -0600426DM_TEST(dm_test_ordering, UTF_SCAN_PDATA);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700427
428/* Check that we can perform operations on a device (do a ping) */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500429int dm_check_operations(struct unit_test_state *uts, struct udevice *dev,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700430 uint32_t base, struct dm_test_priv *priv)
431{
432 int expected;
433 int pingret;
434
Simon Glass71fa5b42020-12-03 16:55:18 -0700435 /* Getting the child device should allocate plat / priv */
Simon Glassb2c1cac2014-02-26 15:59:21 -0700436 ut_assertok(testfdt_ping(dev, 10, &pingret));
Simon Glass95588622020-12-22 19:30:28 -0700437 ut_assert(dev_get_priv(dev));
438 ut_assert(dev_get_plat(dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700439
440 expected = 10 + base;
441 ut_asserteq(expected, pingret);
442
443 /* Do another ping */
444 ut_assertok(testfdt_ping(dev, 20, &pingret));
445 expected = 20 + base;
446 ut_asserteq(expected, pingret);
447
448 /* Now check the ping_total */
Simon Glass95588622020-12-22 19:30:28 -0700449 priv = dev_get_priv(dev);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700450 ut_asserteq(DM_TEST_START_TOTAL + 10 + 20 + base * 2,
451 priv->ping_total);
452
453 return 0;
454}
455
456/* Check that we can perform operations on devices */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500457static int dm_test_operations(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700458{
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200459 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700460 int i;
461
462 /*
463 * Now check that the ping adds are what we expect. This is using the
464 * ping-add property in each node.
465 */
466 for (i = 0; i < ARRAY_SIZE(test_pdata); i++) {
467 uint32_t base;
468
469 ut_assertok(uclass_get_device(UCLASS_TEST, i, &dev));
470
471 /*
472 * Get the 'reg' property, which tells us what the ping add
Simon Glass71fa5b42020-12-03 16:55:18 -0700473 * should be. We don't use the plat because we want
Simon Glassb2c1cac2014-02-26 15:59:21 -0700474 * to test the code that sets that up (testfdt_drv_probe()).
475 */
476 base = test_pdata[i].ping_add;
477 debug("dev=%d, base=%d\n", i, base);
478
Simon Glass95588622020-12-22 19:30:28 -0700479 ut_assert(!dm_check_operations(uts, dev, base, dev_get_priv(dev)));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700480 }
481
482 return 0;
483}
Simon Glass1a92f832024-08-22 07:57:48 -0600484DM_TEST(dm_test_operations, UTF_SCAN_PDATA);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700485
486/* Remove all drivers and check that things work */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500487static int dm_test_remove(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700488{
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200489 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700490 int i;
491
492 for (i = 0; i < 3; i++) {
493 ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
494 ut_assert(dev);
Simon Glass6211d762020-12-19 10:40:10 -0700495 ut_assertf(dev_get_flags(dev) & DM_FLAG_ACTIVATED,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700496 "Driver %d/%s not activated", i, dev->name);
Stefan Roese80b5bc92017-03-20 12:51:48 +0100497 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glass6211d762020-12-19 10:40:10 -0700498 ut_assertf(!(dev_get_flags(dev) & DM_FLAG_ACTIVATED),
Simon Glassb2c1cac2014-02-26 15:59:21 -0700499 "Driver %d/%s should have deactivated", i,
500 dev->name);
Simon Glass95588622020-12-22 19:30:28 -0700501 ut_assert(!dev_get_priv(dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700502 }
503
504 return 0;
505}
Simon Glass1a92f832024-08-22 07:57:48 -0600506DM_TEST(dm_test_remove, UTF_SCAN_PDATA | UTF_PROBE_TEST);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700507
508/* Remove and recreate everything, check for memory leaks */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500509static int dm_test_leak(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700510{
511 int i;
512
513 for (i = 0; i < 2; i++) {
Simon Glassb2c1cac2014-02-26 15:59:21 -0700514 int ret;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700515
Joe Hershberger3a77be52015-05-20 14:27:27 -0500516 dm_leak_check_start(uts);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700517
Simon Glassb75b15b2020-12-03 16:55:23 -0700518 ut_assertok(dm_scan_plat(false));
Simon Glass5039cab2020-11-28 17:50:09 -0700519 ut_assertok(dm_scan_fdt(false));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700520
Michal Suchanek44322b52022-10-12 21:57:51 +0200521 ret = uclass_probe_all(UCLASS_TEST);
522 ut_assertok(ret);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700523
Joe Hershberger3a77be52015-05-20 14:27:27 -0500524 ut_assertok(dm_leak_check_end(uts));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700525 }
526
527 return 0;
528}
529DM_TEST(dm_test_leak, 0);
530
531/* Test uclass init/destroy methods */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500532static int dm_test_uclass(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700533{
Simon Glass51608c92021-12-16 20:59:32 -0700534 int dev_count, uc_count;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700535 struct uclass *uc;
536
Simon Glass51608c92021-12-16 20:59:32 -0700537 /* We should have just the root device and uclass */
538 dm_get_stats(&dev_count, &uc_count);
539 ut_asserteq(1, dev_count);
540 ut_asserteq(1, uc_count);
541
Simon Glassb2c1cac2014-02-26 15:59:21 -0700542 ut_assertok(uclass_get(UCLASS_TEST, &uc));
543 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
544 ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
Simon Glass95588622020-12-22 19:30:28 -0700545 ut_assert(uclass_get_priv(uc));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700546
Simon Glass51608c92021-12-16 20:59:32 -0700547 dm_get_stats(&dev_count, &uc_count);
548 ut_asserteq(1, dev_count);
549 ut_asserteq(2, uc_count);
550
Simon Glassb2c1cac2014-02-26 15:59:21 -0700551 ut_assertok(uclass_destroy(uc));
552 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
553 ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
554
Simon Glass51608c92021-12-16 20:59:32 -0700555 dm_get_stats(&dev_count, &uc_count);
556 ut_asserteq(1, dev_count);
557 ut_asserteq(1, uc_count);
558
Simon Glassb2c1cac2014-02-26 15:59:21 -0700559 return 0;
560}
561DM_TEST(dm_test_uclass, 0);
562
563/**
564 * create_children() - Create children of a parent node
565 *
566 * @dms: Test system state
567 * @parent: Parent device
568 * @count: Number of children to create
569 * @key: Key value to put in first child. Subsequence children
570 * receive an incrementing value
571 * @child: If not NULL, then the child device pointers are written into
572 * this array.
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100573 * Return: 0 if OK, -ve on error
Simon Glassb2c1cac2014-02-26 15:59:21 -0700574 */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500575static int create_children(struct unit_test_state *uts, struct udevice *parent,
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200576 int count, int key, struct udevice *child[])
Simon Glassb2c1cac2014-02-26 15:59:21 -0700577{
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200578 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700579 int i;
580
581 for (i = 0; i < count; i++) {
582 struct dm_test_pdata *pdata;
583
Simon Glassfef72b72014-07-23 06:55:03 -0600584 ut_assertok(device_bind_by_name(parent, false,
585 &driver_info_manual, &dev));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700586 pdata = calloc(1, sizeof(*pdata));
587 pdata->ping_add = key + i;
Simon Glass95588622020-12-22 19:30:28 -0700588 dev_set_plat(dev, pdata);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700589 if (child)
590 child[i] = dev;
591 }
592
593 return 0;
594}
595
596#define NODE_COUNT 10
597
Joe Hershberger3a77be52015-05-20 14:27:27 -0500598static int dm_test_children(struct unit_test_state *uts)
Simon Glassb2c1cac2014-02-26 15:59:21 -0700599{
Heiko Schocherb74fcb42014-05-22 12:43:05 +0200600 struct udevice *top[NODE_COUNT];
601 struct udevice *child[NODE_COUNT];
602 struct udevice *grandchild[NODE_COUNT];
603 struct udevice *dev;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700604 int total;
605 int ret;
606 int i;
607
608 /* We don't care about the numbering for this test */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700609 uts->skip_post_probe = 1;
Simon Glassb2c1cac2014-02-26 15:59:21 -0700610
611 ut_assert(NODE_COUNT > 5);
612
613 /* First create 10 top-level children */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700614 ut_assertok(create_children(uts, uts->root, NODE_COUNT, 0, top));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700615
616 /* Now a few have their own children */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500617 ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL));
618 ut_assertok(create_children(uts, top[5], NODE_COUNT, 5, child));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700619
620 /* And grandchildren */
621 for (i = 0; i < NODE_COUNT; i++)
Joe Hershberger3a77be52015-05-20 14:27:27 -0500622 ut_assertok(create_children(uts, child[i], NODE_COUNT, 50 * i,
Simon Glassb2c1cac2014-02-26 15:59:21 -0700623 i == 2 ? grandchild : NULL));
624
625 /* Check total number of devices */
626 total = NODE_COUNT * (3 + NODE_COUNT);
627 ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_BIND]);
628
629 /* Try probing one of the grandchildren */
630 ut_assertok(uclass_get_device(UCLASS_TEST,
631 NODE_COUNT * 3 + 2 * NODE_COUNT, &dev));
632 ut_asserteq_ptr(grandchild[0], dev);
633
634 /*
635 * This should have probed the child and top node also, for a total
636 * of 3 nodes.
637 */
638 ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
639
640 /* Probe the other grandchildren */
641 for (i = 1; i < NODE_COUNT; i++)
642 ut_assertok(device_probe(grandchild[i]));
643
644 ut_asserteq(2 + NODE_COUNT, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
645
646 /* Probe everything */
Michal Suchanek44322b52022-10-12 21:57:51 +0200647 ret = uclass_probe_all(UCLASS_TEST);
Simon Glassb2c1cac2014-02-26 15:59:21 -0700648 ut_assertok(ret);
649
650 ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_PROBE]);
651
652 /* Remove a top-level child and check that the children are removed */
Stefan Roese80b5bc92017-03-20 12:51:48 +0100653 ut_assertok(device_remove(top[2], DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700654 ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_REMOVE]);
655 dm_testdrv_op_count[DM_TEST_OP_REMOVE] = 0;
656
657 /* Try one with grandchildren */
658 ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev));
659 ut_asserteq_ptr(dev, top[5]);
Stefan Roese80b5bc92017-03-20 12:51:48 +0100660 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassb2c1cac2014-02-26 15:59:21 -0700661 ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT),
662 dm_testdrv_op_count[DM_TEST_OP_REMOVE]);
663
664 /* Try the same with unbind */
665 ut_assertok(device_unbind(top[2]));
666 ut_asserteq(NODE_COUNT + 1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
667 dm_testdrv_op_count[DM_TEST_OP_UNBIND] = 0;
668
669 /* Try one with grandchildren */
670 ut_assertok(uclass_get_device(UCLASS_TEST, 5, &dev));
671 ut_asserteq_ptr(dev, top[6]);
672 ut_assertok(device_unbind(top[5]));
673 ut_asserteq(1 + NODE_COUNT * (1 + NODE_COUNT),
674 dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
675
676 return 0;
677}
678DM_TEST(dm_test_children, 0);
Simon Glassfef72b72014-07-23 06:55:03 -0600679
Claudiu Bezneabf5b8232020-09-07 17:46:33 +0300680static int dm_test_device_reparent(struct unit_test_state *uts)
681{
Claudiu Bezneabf5b8232020-09-07 17:46:33 +0300682 struct udevice *top[NODE_COUNT];
683 struct udevice *child[NODE_COUNT];
684 struct udevice *grandchild[NODE_COUNT];
685 struct udevice *dev;
686 int total;
687 int ret;
688 int i;
689
690 /* We don't care about the numbering for this test */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700691 uts->skip_post_probe = 1;
Claudiu Bezneabf5b8232020-09-07 17:46:33 +0300692
693 ut_assert(NODE_COUNT > 5);
694
695 /* First create 10 top-level children */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700696 ut_assertok(create_children(uts, uts->root, NODE_COUNT, 0, top));
Claudiu Bezneabf5b8232020-09-07 17:46:33 +0300697
698 /* Now a few have their own children */
699 ut_assertok(create_children(uts, top[2], NODE_COUNT, 2, NULL));
700 ut_assertok(create_children(uts, top[5], NODE_COUNT, 5, child));
701
702 /* And grandchildren */
703 for (i = 0; i < NODE_COUNT; i++)
704 ut_assertok(create_children(uts, child[i], NODE_COUNT, 50 * i,
705 i == 2 ? grandchild : NULL));
706
707 /* Check total number of devices */
708 total = NODE_COUNT * (3 + NODE_COUNT);
709 ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_BIND]);
710
711 /* Probe everything */
712 for (i = 0; i < total; i++)
713 ut_assertok(uclass_get_device(UCLASS_TEST, i, &dev));
714
715 /* Re-parent top-level children with no grandchildren. */
716 ut_assertok(device_reparent(top[3], top[0]));
717 /* try to get devices */
718 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
719 dev;
720 ret = uclass_find_next_device(&dev)) {
721 ut_assert(!ret);
722 ut_assertnonnull(dev);
723 }
724
725 ut_assertok(device_reparent(top[4], top[0]));
726 /* try to get devices */
727 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
728 dev;
729 ret = uclass_find_next_device(&dev)) {
730 ut_assert(!ret);
731 ut_assertnonnull(dev);
732 }
733
734 /* Re-parent top-level children with grandchildren. */
735 ut_assertok(device_reparent(top[2], top[0]));
736 /* try to get devices */
737 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
738 dev;
739 ret = uclass_find_next_device(&dev)) {
740 ut_assert(!ret);
741 ut_assertnonnull(dev);
742 }
743
744 ut_assertok(device_reparent(top[5], top[2]));
745 /* try to get devices */
746 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
747 dev;
748 ret = uclass_find_next_device(&dev)) {
749 ut_assert(!ret);
750 ut_assertnonnull(dev);
751 }
752
753 /* Re-parent grandchildren. */
754 ut_assertok(device_reparent(grandchild[0], top[1]));
755 /* try to get devices */
756 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
757 dev;
758 ret = uclass_find_next_device(&dev)) {
759 ut_assert(!ret);
760 ut_assertnonnull(dev);
761 }
762
763 ut_assertok(device_reparent(grandchild[1], top[1]));
764 /* try to get devices */
765 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
766 dev;
767 ret = uclass_find_next_device(&dev)) {
768 ut_assert(!ret);
769 ut_assertnonnull(dev);
770 }
771
772 /* Remove re-pareneted devices. */
773 ut_assertok(device_remove(top[3], DM_REMOVE_NORMAL));
774 /* try to get devices */
775 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
776 dev;
777 ret = uclass_find_next_device(&dev)) {
778 ut_assert(!ret);
779 ut_assertnonnull(dev);
780 }
781
782 ut_assertok(device_remove(top[4], DM_REMOVE_NORMAL));
783 /* try to get devices */
784 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
785 dev;
786 ret = uclass_find_next_device(&dev)) {
787 ut_assert(!ret);
788 ut_assertnonnull(dev);
789 }
790
791 ut_assertok(device_remove(top[5], DM_REMOVE_NORMAL));
792 /* try to get devices */
793 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
794 dev;
795 ret = uclass_find_next_device(&dev)) {
796 ut_assert(!ret);
797 ut_assertnonnull(dev);
798 }
799
800 ut_assertok(device_remove(top[2], DM_REMOVE_NORMAL));
801 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
802 dev;
803 ret = uclass_find_next_device(&dev)) {
804 ut_assert(!ret);
805 ut_assertnonnull(dev);
806 }
807
808 ut_assertok(device_remove(grandchild[0], DM_REMOVE_NORMAL));
809 /* try to get devices */
810 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
811 dev;
812 ret = uclass_find_next_device(&dev)) {
813 ut_assert(!ret);
814 ut_assertnonnull(dev);
815 }
816
817 ut_assertok(device_remove(grandchild[1], DM_REMOVE_NORMAL));
818 /* try to get devices */
819 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
820 dev;
821 ret = uclass_find_next_device(&dev)) {
822 ut_assert(!ret);
823 ut_assertnonnull(dev);
824 }
825
826 /* Try the same with unbind */
827 ut_assertok(device_unbind(top[3]));
828 ut_assertok(device_unbind(top[4]));
829 ut_assertok(device_unbind(top[5]));
830 ut_assertok(device_unbind(top[2]));
831
832 ut_assertok(device_unbind(grandchild[0]));
833 ut_assertok(device_unbind(grandchild[1]));
834
835 return 0;
836}
837DM_TEST(dm_test_device_reparent, 0);
838
Simon Glassfef72b72014-07-23 06:55:03 -0600839/* Test that pre-relocation devices work as expected */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500840static int dm_test_pre_reloc(struct unit_test_state *uts)
Simon Glassfef72b72014-07-23 06:55:03 -0600841{
842 struct udevice *dev;
843
844 /* The normal driver should refuse to bind before relocation */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700845 ut_asserteq(-EPERM, device_bind_by_name(uts->root, true,
Simon Glassfef72b72014-07-23 06:55:03 -0600846 &driver_info_manual, &dev));
847
848 /* But this one is marked pre-reloc */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700849 ut_assertok(device_bind_by_name(uts->root, true,
Simon Glassfef72b72014-07-23 06:55:03 -0600850 &driver_info_pre_reloc, &dev));
851
852 return 0;
853}
854DM_TEST(dm_test_pre_reloc, 0);
Simon Glassde708672014-07-23 06:55:15 -0600855
Stefan Roeseeaffda72017-03-27 11:02:43 +0200856/*
857 * Test that removal of devices, either via the "normal" device_remove()
858 * API or via the device driver selective flag works as expected
859 */
860static int dm_test_remove_active_dma(struct unit_test_state *uts)
861{
Stefan Roeseeaffda72017-03-27 11:02:43 +0200862 struct udevice *dev;
863
Simon Glassb98bfbc2021-03-07 17:34:57 -0700864 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_act_dma,
Stefan Roeseeaffda72017-03-27 11:02:43 +0200865 &dev));
866 ut_assert(dev);
867
868 /* Probe the device */
869 ut_assertok(device_probe(dev));
870
871 /* Test if device is active right now */
872 ut_asserteq(true, device_active(dev));
873
874 /* Remove the device via selective remove flag */
875 dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
876
877 /* Test if device is inactive right now */
878 ut_asserteq(false, device_active(dev));
879
880 /* Probe the device again */
881 ut_assertok(device_probe(dev));
882
883 /* Test if device is active right now */
884 ut_asserteq(true, device_active(dev));
885
886 /* Remove the device via "normal" remove API */
887 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
888
889 /* Test if device is inactive right now */
890 ut_asserteq(false, device_active(dev));
891
892 /*
893 * Test if a device without the active DMA flags is not removed upon
894 * the active DMA remove call
895 */
896 ut_assertok(device_unbind(dev));
Simon Glassb98bfbc2021-03-07 17:34:57 -0700897 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Stefan Roeseeaffda72017-03-27 11:02:43 +0200898 &dev));
899 ut_assert(dev);
900
901 /* Probe the device */
902 ut_assertok(device_probe(dev));
903
904 /* Test if device is active right now */
905 ut_asserteq(true, device_active(dev));
906
907 /* Remove the device via selective remove flag */
908 dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
909
910 /* Test if device is still active right now */
911 ut_asserteq(true, device_active(dev));
912
913 return 0;
914}
915DM_TEST(dm_test_remove_active_dma, 0);
916
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700917/* Test removal of 'vital' devices */
918static int dm_test_remove_vital(struct unit_test_state *uts)
919{
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700920 struct udevice *normal, *dma, *vital, *dma_vital;
921
922 /* Skip the behaviour in test_post_probe() */
Simon Glassb98bfbc2021-03-07 17:34:57 -0700923 uts->skip_post_probe = 1;
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700924
Simon Glassb98bfbc2021-03-07 17:34:57 -0700925 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700926 &normal));
927 ut_assertnonnull(normal);
928
Simon Glassb98bfbc2021-03-07 17:34:57 -0700929 ut_assertok(device_bind_by_name(uts->root, false, &driver_info_act_dma,
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700930 &dma));
931 ut_assertnonnull(dma);
932
Simon Glassb98bfbc2021-03-07 17:34:57 -0700933 ut_assertok(device_bind_by_name(uts->root, false,
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700934 &driver_info_vital_clk, &vital));
935 ut_assertnonnull(vital);
936
Simon Glassb98bfbc2021-03-07 17:34:57 -0700937 ut_assertok(device_bind_by_name(uts->root, false,
Marek Vasutabbdbbd2021-01-24 14:32:46 -0700938 &driver_info_act_dma_vital_clk,
939 &dma_vital));
940 ut_assertnonnull(dma_vital);
941
942 /* Probe the devices */
943 ut_assertok(device_probe(normal));
944 ut_assertok(device_probe(dma));
945 ut_assertok(device_probe(vital));
946 ut_assertok(device_probe(dma_vital));
947
948 /* Check that devices are active right now */
949 ut_asserteq(true, device_active(normal));
950 ut_asserteq(true, device_active(dma));
951 ut_asserteq(true, device_active(vital));
952 ut_asserteq(true, device_active(dma_vital));
953
954 /* Remove active devices via selective remove flag */
955 dm_remove_devices_flags(DM_REMOVE_NON_VITAL | DM_REMOVE_ACTIVE_ALL);
956
957 /*
958 * Check that this only has an effect on the dma device, since two
959 * devices are vital and the third does not have active DMA
960 */
961 ut_asserteq(true, device_active(normal));
962 ut_asserteq(false, device_active(dma));
963 ut_asserteq(true, device_active(vital));
964 ut_asserteq(true, device_active(dma_vital));
965
966 /* Remove active devices via selective remove flag */
967 ut_assertok(device_probe(dma));
968 dm_remove_devices_flags(DM_REMOVE_ACTIVE_ALL);
969
970 /* This should have affected both active-dma devices */
971 ut_asserteq(true, device_active(normal));
972 ut_asserteq(false, device_active(dma));
973 ut_asserteq(true, device_active(vital));
974 ut_asserteq(false, device_active(dma_vital));
975
976 /* Remove non-vital devices */
977 ut_assertok(device_probe(dma));
978 ut_assertok(device_probe(dma_vital));
979 dm_remove_devices_flags(DM_REMOVE_NON_VITAL);
980
981 /* This should have affected only non-vital devices */
982 ut_asserteq(false, device_active(normal));
983 ut_asserteq(false, device_active(dma));
984 ut_asserteq(true, device_active(vital));
985 ut_asserteq(true, device_active(dma_vital));
986
987 /* Remove vital devices via normal remove flag */
988 ut_assertok(device_probe(normal));
989 ut_assertok(device_probe(dma));
990 dm_remove_devices_flags(DM_REMOVE_NORMAL);
991
992 /* Check that all devices are inactive right now */
993 ut_asserteq(false, device_active(normal));
994 ut_asserteq(false, device_active(dma));
995 ut_asserteq(false, device_active(vital));
996 ut_asserteq(false, device_active(dma_vital));
997
998 return 0;
999}
1000DM_TEST(dm_test_remove_vital, 0);
1001
Joe Hershberger3a77be52015-05-20 14:27:27 -05001002static int dm_test_uclass_before_ready(struct unit_test_state *uts)
Simon Glassde708672014-07-23 06:55:15 -06001003{
1004 struct uclass *uc;
1005
1006 ut_assertok(uclass_get(UCLASS_TEST, &uc));
1007
Simon Glass51a0eac2015-04-19 07:21:02 -06001008 gd->dm_root = NULL;
Simon Glass51a0eac2015-04-19 07:21:02 -06001009 memset(&gd->uclass_root, '\0', sizeof(gd->uclass_root));
1010
Simon Glassde708672014-07-23 06:55:15 -06001011 ut_asserteq_ptr(NULL, uclass_find(UCLASS_TEST));
Simon Glass8e9eacf2021-08-01 12:05:23 -06001012 ut_asserteq(-EDEADLK, uclass_get(UCLASS_TEST, &uc));
Simon Glassde708672014-07-23 06:55:15 -06001013
1014 return 0;
1015}
Simon Glassde708672014-07-23 06:55:15 -06001016DM_TEST(dm_test_uclass_before_ready, 0);
Simon Glass98fd5d12015-01-25 08:27:04 -07001017
Joe Hershberger3a77be52015-05-20 14:27:27 -05001018static int dm_test_uclass_devices_find(struct unit_test_state *uts)
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001019{
1020 struct udevice *dev;
1021 int ret;
1022
1023 for (ret = uclass_find_first_device(UCLASS_TEST, &dev);
1024 dev;
1025 ret = uclass_find_next_device(&dev)) {
1026 ut_assert(!ret);
Heinrich Schuchardt6c2a8712020-07-17 00:20:14 +02001027 ut_assertnonnull(dev);
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001028 }
1029
Simon Glass0bb44272019-09-25 08:55:55 -06001030 ut_assertok(uclass_find_first_device(UCLASS_TEST_DUMMY, &dev));
Heinrich Schuchardt6c2a8712020-07-17 00:20:14 +02001031 ut_assertnull(dev);
Marcel Ziswiler75ec16f2019-02-01 16:01:07 +01001032
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001033 return 0;
1034}
Simon Glass1a92f832024-08-22 07:57:48 -06001035DM_TEST(dm_test_uclass_devices_find, UTF_SCAN_PDATA);
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001036
Joe Hershberger3a77be52015-05-20 14:27:27 -05001037static int dm_test_uclass_devices_find_by_name(struct unit_test_state *uts)
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001038{
1039 struct udevice *finddev;
1040 struct udevice *testdev;
1041 int findret, ret;
1042
1043 /*
1044 * For each test device found in fdt like: "a-test", "b-test", etc.,
1045 * use its name and try to find it by uclass_find_device_by_name().
1046 * Then, on success check if:
1047 * - current 'testdev' name is equal to the returned 'finddev' name
1048 * - current 'testdev' pointer is equal to the returned 'finddev'
1049 *
1050 * We assume that, each uclass's device name is unique, so if not, then
1051 * this will fail on checking condition: testdev == finddev, since the
1052 * uclass_find_device_by_name(), returns the first device by given name.
1053 */
1054 for (ret = uclass_find_first_device(UCLASS_TEST_FDT, &testdev);
1055 testdev;
1056 ret = uclass_find_next_device(&testdev)) {
1057 ut_assertok(ret);
Heinrich Schuchardt6c2a8712020-07-17 00:20:14 +02001058 ut_assertnonnull(testdev);
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001059
1060 findret = uclass_find_device_by_name(UCLASS_TEST_FDT,
1061 testdev->name,
1062 &finddev);
1063
1064 ut_assertok(findret);
1065 ut_assert(testdev);
1066 ut_asserteq_str(testdev->name, finddev->name);
1067 ut_asserteq_ptr(testdev, finddev);
1068 }
1069
1070 return 0;
1071}
Simon Glass1a92f832024-08-22 07:57:48 -06001072DM_TEST(dm_test_uclass_devices_find_by_name, UTF_SCAN_FDT);
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001073
Joe Hershberger3a77be52015-05-20 14:27:27 -05001074static int dm_test_uclass_devices_get(struct unit_test_state *uts)
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001075{
1076 struct udevice *dev;
1077 int ret;
1078
Michal Suchanek98e1ada2022-10-12 21:58:09 +02001079 for (ret = uclass_first_device_check(UCLASS_TEST, &dev);
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001080 dev;
Michal Suchanek98e1ada2022-10-12 21:58:09 +02001081 ret = uclass_next_device_check(&dev)) {
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001082 ut_assert(!ret);
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001083 ut_assert(device_active(dev));
1084 }
1085
1086 return 0;
1087}
Simon Glass1a92f832024-08-22 07:57:48 -06001088DM_TEST(dm_test_uclass_devices_get, UTF_SCAN_PDATA);
Przemyslaw Marczak1e0a7f22015-04-15 13:07:20 +02001089
Joe Hershberger3a77be52015-05-20 14:27:27 -05001090static int dm_test_uclass_devices_get_by_name(struct unit_test_state *uts)
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001091{
1092 struct udevice *finddev;
1093 struct udevice *testdev;
1094 int ret, findret;
1095
1096 /*
1097 * For each test device found in fdt like: "a-test", "b-test", etc.,
1098 * use its name and try to get it by uclass_get_device_by_name().
1099 * On success check if:
1100 * - returned finddev' is active
1101 * - current 'testdev' name is equal to the returned 'finddev' name
1102 * - current 'testdev' pointer is equal to the returned 'finddev'
1103 *
1104 * We asserts that the 'testdev' is active on each loop entry, so we
1105 * could be sure that the 'finddev' is activated too, but for sure
1106 * we check it again.
1107 *
1108 * We assume that, each uclass's device name is unique, so if not, then
1109 * this will fail on checking condition: testdev == finddev, since the
1110 * uclass_get_device_by_name(), returns the first device by given name.
1111 */
Michal Suchanek98e1ada2022-10-12 21:58:09 +02001112 for (ret = uclass_first_device_check(UCLASS_TEST_FDT, &testdev);
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001113 testdev;
Michal Suchanek98e1ada2022-10-12 21:58:09 +02001114 ret = uclass_next_device_check(&testdev)) {
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001115 ut_assertok(ret);
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001116 ut_assert(device_active(testdev));
1117
1118 findret = uclass_get_device_by_name(UCLASS_TEST_FDT,
1119 testdev->name,
1120 &finddev);
1121
1122 ut_assertok(findret);
1123 ut_assert(finddev);
1124 ut_assert(device_active(finddev));
1125 ut_asserteq_str(testdev->name, finddev->name);
1126 ut_asserteq_ptr(testdev, finddev);
1127 }
1128
1129 return 0;
1130}
Simon Glass1a92f832024-08-22 07:57:48 -06001131DM_TEST(dm_test_uclass_devices_get_by_name, UTF_SCAN_FDT);
Przemyslaw Marczak2eff02f2015-04-20 13:32:33 +02001132
Joe Hershberger3a77be52015-05-20 14:27:27 -05001133static int dm_test_device_get_uclass_id(struct unit_test_state *uts)
Simon Glass98fd5d12015-01-25 08:27:04 -07001134{
1135 struct udevice *dev;
1136
1137 ut_assertok(uclass_get_device(UCLASS_TEST, 0, &dev));
1138 ut_asserteq(UCLASS_TEST, device_get_uclass_id(dev));
1139
1140 return 0;
1141}
Simon Glass1a92f832024-08-22 07:57:48 -06001142DM_TEST(dm_test_device_get_uclass_id, UTF_SCAN_PDATA);
Simon Glass70e35b42017-12-28 13:14:15 -07001143
1144static int dm_test_uclass_names(struct unit_test_state *uts)
1145{
1146 ut_asserteq_str("test", uclass_get_name(UCLASS_TEST));
1147 ut_asserteq(UCLASS_TEST, uclass_get_by_name("test"));
1148
Simon Glassf1f519f2022-04-24 23:30:59 -06001149 ut_asserteq(UCLASS_SPI, uclass_get_by_name("spi"));
1150
Simon Glass70e35b42017-12-28 13:14:15 -07001151 return 0;
1152}
Simon Glass1a92f832024-08-22 07:57:48 -06001153DM_TEST(dm_test_uclass_names, UTF_SCAN_PDATA);
Simon Glassb775e872018-10-01 12:22:07 -06001154
1155static int dm_test_inactive_child(struct unit_test_state *uts)
1156{
Simon Glassb775e872018-10-01 12:22:07 -06001157 struct udevice *parent, *dev1, *dev2;
1158
1159 /* Skip the behaviour in test_post_probe() */
Simon Glassb98bfbc2021-03-07 17:34:57 -07001160 uts->skip_post_probe = 1;
Simon Glassb775e872018-10-01 12:22:07 -06001161
1162 ut_assertok(uclass_first_device_err(UCLASS_TEST, &parent));
1163
1164 /*
1165 * Create a child but do not activate it. Calling the function again
1166 * should return the same child.
1167 */
1168 ut_asserteq(-ENODEV, device_find_first_inactive_child(parent,
1169 UCLASS_TEST, &dev1));
Simon Glass65130cd2020-12-28 20:34:56 -07001170 ut_assertok(device_bind(parent, DM_DRIVER_GET(test_drv),
Simon Glass884870f2020-11-28 17:50:01 -07001171 "test_child", 0, ofnode_null(), &dev1));
Simon Glassb775e872018-10-01 12:22:07 -06001172
1173 ut_assertok(device_find_first_inactive_child(parent, UCLASS_TEST,
1174 &dev2));
1175 ut_asserteq_ptr(dev1, dev2);
1176
1177 ut_assertok(device_probe(dev1));
1178 ut_asserteq(-ENODEV, device_find_first_inactive_child(parent,
1179 UCLASS_TEST, &dev2));
1180
1181 return 0;
1182}
Simon Glass1a92f832024-08-22 07:57:48 -06001183DM_TEST(dm_test_inactive_child, UTF_SCAN_PDATA);
Simon Glass6a109b32020-12-16 21:20:10 -07001184
1185/* Make sure all bound devices have a sequence number */
1186static int dm_test_all_have_seq(struct unit_test_state *uts)
1187{
1188 struct udevice *dev;
1189 struct uclass *uc;
1190
Simon Glass784cd9e2020-12-19 10:40:17 -07001191 list_for_each_entry(uc, gd->uclass_root, sibling_node) {
Simon Glass6a109b32020-12-16 21:20:10 -07001192 list_for_each_entry(dev, &uc->dev_head, uclass_node) {
Simon Glass5e349922020-12-19 10:40:09 -07001193 if (dev->seq_ == -1)
Simon Glass6a109b32020-12-16 21:20:10 -07001194 printf("Device '%s' has no seq (%d)\n",
Simon Glass5e349922020-12-19 10:40:09 -07001195 dev->name, dev->seq_);
1196 ut_assert(dev->seq_ != -1);
Simon Glass6a109b32020-12-16 21:20:10 -07001197 }
1198 }
1199
1200 return 0;
1201}
Simon Glass1a92f832024-08-22 07:57:48 -06001202DM_TEST(dm_test_all_have_seq, UTF_SCAN_PDATA);
Nicolas Saenz Julienne892e9b42021-01-12 13:55:25 +01001203
Simon Glass26974252021-07-05 16:32:42 -06001204#if CONFIG_IS_ENABLED(DM_DMA)
Nicolas Saenz Julienne892e9b42021-01-12 13:55:25 +01001205static int dm_test_dma_offset(struct unit_test_state *uts)
1206{
1207 struct udevice *dev;
1208 ofnode node;
1209
1210 /* Make sure the bus's dma-ranges aren't taken into account here */
1211 node = ofnode_path("/mmio-bus@0");
1212 ut_assert(ofnode_valid(node));
1213 ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, &dev));
1214 ut_asserteq_64(0, dev->dma_offset);
1215
1216 /* Device behind a bus with dma-ranges */
1217 node = ofnode_path("/mmio-bus@0/subnode@0");
1218 ut_assert(ofnode_valid(node));
1219 ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, &dev));
1220 ut_asserteq_64(-0x10000000ULL, dev->dma_offset);
1221
1222 /* This one has no dma-ranges */
1223 node = ofnode_path("/mmio-bus@1");
1224 ut_assert(ofnode_valid(node));
1225 ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_BUS, node, &dev));
1226 node = ofnode_path("/mmio-bus@1/subnode@0");
1227 ut_assert(ofnode_valid(node));
1228 ut_assertok(uclass_get_device_by_ofnode(UCLASS_TEST_FDT, node, &dev));
1229 ut_asserteq_64(0, dev->dma_offset);
1230
1231 return 0;
1232}
Simon Glass1a92f832024-08-22 07:57:48 -06001233DM_TEST(dm_test_dma_offset, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass26974252021-07-05 16:32:42 -06001234#endif
Simon Glass51608c92021-12-16 20:59:32 -07001235
1236/* Test dm_get_stats() */
1237static int dm_test_get_stats(struct unit_test_state *uts)
1238{
1239 int dev_count, uc_count;
1240
1241 dm_get_stats(&dev_count, &uc_count);
1242 ut_assert(dev_count > 50);
1243 ut_assert(uc_count > 30);
1244
1245 return 0;
1246}
Simon Glass1a92f832024-08-22 07:57:48 -06001247DM_TEST(dm_test_get_stats, UTF_SCAN_FDT);
Simon Glass9670f7d2022-04-24 23:31:00 -06001248
1249/* Test uclass_find_device_by_name() */
1250static int dm_test_uclass_find_device(struct unit_test_state *uts)
1251{
1252 struct udevice *dev;
1253
1254 ut_assertok(uclass_find_device_by_name(UCLASS_I2C, "i2c@0", &dev));
1255 ut_asserteq(-ENODEV,
1256 uclass_find_device_by_name(UCLASS_I2C, "i2c@0x", &dev));
1257 ut_assertok(uclass_find_device_by_namelen(UCLASS_I2C, "i2c@0x", 5,
1258 &dev));
1259
1260 return 0;
1261}
Simon Glass1a92f832024-08-22 07:57:48 -06001262DM_TEST(dm_test_uclass_find_device, UTF_SCAN_FDT);
Simon Glassd1f12cf2022-05-08 04:39:24 -06001263
1264/* Test getting information about tags attached to devices */
1265static int dm_test_dev_get_attach(struct unit_test_state *uts)
1266{
1267 struct udevice *dev;
1268
1269 ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev));
1270 ut_asserteq_str("a-test", dev->name);
1271
1272 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PLAT));
1273 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PRIV));
1274 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_UC_PRIV));
1275 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_UC_PLAT));
1276 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PLAT));
1277 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PRIV));
1278
1279 ut_asserteq(sizeof(struct dm_test_pdata),
1280 dev_get_attach_size(dev, DM_TAG_PLAT));
1281 ut_asserteq(sizeof(struct dm_test_priv),
1282 dev_get_attach_size(dev, DM_TAG_PRIV));
1283 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_UC_PRIV));
1284 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_UC_PLAT));
1285 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PLAT));
1286 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PRIV));
1287
1288 return 0;
1289}
Simon Glass1a92f832024-08-22 07:57:48 -06001290DM_TEST(dm_test_dev_get_attach, UTF_SCAN_FDT);
Simon Glassd1f12cf2022-05-08 04:39:24 -06001291
1292/* Test getting information about tags attached to bus devices */
1293static int dm_test_dev_get_attach_bus(struct unit_test_state *uts)
1294{
1295 struct udevice *dev, *child;
1296
1297 ut_assertok(uclass_first_device_err(UCLASS_TEST_BUS, &dev));
1298 ut_asserteq_str("some-bus", dev->name);
1299
1300 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PLAT));
1301 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_PRIV));
1302 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_UC_PRIV));
1303 ut_assertnonnull(dev_get_attach_ptr(dev, DM_TAG_UC_PLAT));
1304 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PLAT));
1305 ut_assertnull(dev_get_attach_ptr(dev, DM_TAG_PARENT_PRIV));
1306
1307 ut_asserteq(sizeof(struct dm_test_pdata),
1308 dev_get_attach_size(dev, DM_TAG_PLAT));
1309 ut_asserteq(sizeof(struct dm_test_priv),
1310 dev_get_attach_size(dev, DM_TAG_PRIV));
1311 ut_asserteq(sizeof(struct dm_test_uclass_priv),
1312 dev_get_attach_size(dev, DM_TAG_UC_PRIV));
1313 ut_asserteq(sizeof(struct dm_test_uclass_plat),
1314 dev_get_attach_size(dev, DM_TAG_UC_PLAT));
1315 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PLAT));
1316 ut_asserteq(0, dev_get_attach_size(dev, DM_TAG_PARENT_PRIV));
1317
1318 /* Now try the child of the bus */
1319 ut_assertok(device_first_child_err(dev, &child));
1320 ut_asserteq_str("c-test@5", child->name);
1321
1322 ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PLAT));
1323 ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PRIV));
1324 ut_assertnull(dev_get_attach_ptr(child, DM_TAG_UC_PRIV));
1325 ut_assertnull(dev_get_attach_ptr(child, DM_TAG_UC_PLAT));
1326 ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PARENT_PLAT));
1327 ut_assertnonnull(dev_get_attach_ptr(child, DM_TAG_PARENT_PRIV));
1328
1329 ut_asserteq(sizeof(struct dm_test_pdata),
1330 dev_get_attach_size(child, DM_TAG_PLAT));
1331 ut_asserteq(sizeof(struct dm_test_priv),
1332 dev_get_attach_size(child, DM_TAG_PRIV));
1333 ut_asserteq(0, dev_get_attach_size(child, DM_TAG_UC_PRIV));
1334 ut_asserteq(0, dev_get_attach_size(child, DM_TAG_UC_PLAT));
1335 ut_asserteq(sizeof(struct dm_test_parent_plat),
1336 dev_get_attach_size(child, DM_TAG_PARENT_PLAT));
1337 ut_asserteq(sizeof(struct dm_test_parent_data),
1338 dev_get_attach_size(child, DM_TAG_PARENT_PRIV));
1339
1340 return 0;
1341}
Simon Glass1a92f832024-08-22 07:57:48 -06001342DM_TEST(dm_test_dev_get_attach_bus, UTF_SCAN_FDT);
Simon Glassbe1621b2022-05-08 04:39:25 -06001343
1344/* Test getting information about tags attached to bus devices */
1345static int dm_test_dev_get_mem(struct unit_test_state *uts)
1346{
1347 struct dm_stats stats;
1348
1349 dm_get_mem(&stats);
1350
1351 return 0;
1352}
Simon Glass1a92f832024-08-22 07:57:48 -06001353DM_TEST(dm_test_dev_get_mem, UTF_SCAN_FDT);