]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
1ca7e206 SG |
2 | /* |
3 | * Copyright (c) 2014 Google, Inc | |
1ca7e206 SG |
4 | */ |
5 | ||
9f8037ea | 6 | #ifdef CONFIG_SANDBOX |
f7ae49fc | 7 | #include <log.h> |
9f8037ea SG |
8 | #include <os.h> |
9 | #endif | |
1ca7e206 | 10 | #include <dm.h> |
401d1c4f | 11 | #include <asm/global_data.h> |
240b9320 | 12 | #include <dm/device.h> |
e59f458d | 13 | #include <dm/device-internal.h> |
1ca7e206 | 14 | #include <dm/test.h> |
cdc133bd | 15 | #include <dm/uclass-internal.h> |
1ca7e206 | 16 | #include <dm/util.h> |
0e1fad43 | 17 | #include <test/test.h> |
e721b882 | 18 | #include <test/ut.h> |
1ca7e206 SG |
19 | |
20 | DECLARE_GLOBAL_DATA_PTR; | |
21 | ||
1ca7e206 | 22 | /* Test that we can probe for children */ |
e721b882 | 23 | static int dm_test_bus_children(struct unit_test_state *uts) |
1ca7e206 | 24 | { |
88e6a60e | 25 | int num_devices = 9; |
1ca7e206 SG |
26 | struct udevice *bus; |
27 | struct uclass *uc; | |
28 | ||
29 | ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc)); | |
30 | ut_asserteq(num_devices, list_count_items(&uc->dev_head)); | |
31 | ||
32 | /* Probe the bus, which should yield 3 more devices */ | |
33 | ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); | |
34 | num_devices += 3; | |
35 | ||
36 | ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc)); | |
37 | ut_asserteq(num_devices, list_count_items(&uc->dev_head)); | |
38 | ||
e721b882 | 39 | ut_assert(!dm_check_devices(uts, num_devices)); |
1ca7e206 SG |
40 | |
41 | return 0; | |
42 | } | |
e180c2b1 | 43 | DM_TEST(dm_test_bus_children, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |
997c87bb SG |
44 | |
45 | /* Test our functions for accessing children */ | |
e721b882 | 46 | static int dm_test_bus_children_funcs(struct unit_test_state *uts) |
997c87bb SG |
47 | { |
48 | const void *blob = gd->fdt_blob; | |
49 | struct udevice *bus, *dev; | |
50 | int node; | |
51 | ||
52 | ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); | |
53 | ||
54 | /* device_get_child() */ | |
55 | ut_assertok(device_get_child(bus, 0, &dev)); | |
56 | ut_asserteq(-ENODEV, device_get_child(bus, 4, &dev)); | |
57 | ut_assertok(device_get_child_by_seq(bus, 5, &dev)); | |
73466df3 | 58 | ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED); |
997c87bb SG |
59 | ut_asserteq_str("c-test@5", dev->name); |
60 | ||
61 | /* Device with sequence number 0 should be accessible */ | |
99175919 SG |
62 | ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, &dev)); |
63 | ut_assertok(device_find_child_by_seq(bus, 0, &dev)); | |
73466df3 | 64 | ut_assert(!(dev_get_flags(dev) & DM_FLAG_ACTIVATED)); |
99175919 | 65 | ut_asserteq(0, device_find_child_by_seq(bus, 0, &dev)); |
997c87bb | 66 | ut_assertok(device_get_child_by_seq(bus, 0, &dev)); |
73466df3 | 67 | ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED); |
99175919 | 68 | ut_asserteq(0, device_find_child_by_seq(bus, 0, &dev)); |
997c87bb SG |
69 | |
70 | /* There is no device with sequence number 2 */ | |
99175919 SG |
71 | ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, &dev)); |
72 | ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, &dev)); | |
997c87bb SG |
73 | ut_asserteq(-ENODEV, device_get_child_by_seq(bus, 2, &dev)); |
74 | ||
75 | /* Looking for something that is not a child */ | |
76 | node = fdt_path_offset(blob, "/junk"); | |
77 | ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev)); | |
78 | node = fdt_path_offset(blob, "/d-test"); | |
79 | ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev)); | |
80 | ||
298afb52 SG |
81 | return 0; |
82 | } | |
e180c2b1 | 83 | DM_TEST(dm_test_bus_children_funcs, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |
298afb52 SG |
84 | |
85 | static int dm_test_bus_children_of_offset(struct unit_test_state *uts) | |
86 | { | |
87 | const void *blob = gd->fdt_blob; | |
88 | struct udevice *bus, *dev; | |
89 | int node; | |
90 | ||
91 | ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); | |
4f414d39 | 92 | ut_assertnonnull(bus); |
298afb52 | 93 | |
997c87bb SG |
94 | /* Find a valid child */ |
95 | node = fdt_path_offset(blob, "/some-bus/c-test@1"); | |
298afb52 | 96 | ut_assert(node > 0); |
997c87bb | 97 | ut_assertok(device_find_child_by_of_offset(bus, node, &dev)); |
4f414d39 | 98 | ut_assertnonnull(dev); |
73466df3 | 99 | ut_assert(!(dev_get_flags(dev) & DM_FLAG_ACTIVATED)); |
997c87bb | 100 | ut_assertok(device_get_child_by_of_offset(bus, node, &dev)); |
4f414d39 | 101 | ut_assertnonnull(dev); |
73466df3 | 102 | ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED); |
997c87bb SG |
103 | |
104 | return 0; | |
105 | } | |
298afb52 | 106 | DM_TEST(dm_test_bus_children_of_offset, |
e180c2b1 | 107 | UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_FLAT_TREE); |
e59f458d | 108 | |
a8981d4f | 109 | /* Test that we can iterate through children */ |
e721b882 | 110 | static int dm_test_bus_children_iterators(struct unit_test_state *uts) |
a8981d4f SG |
111 | { |
112 | struct udevice *bus, *dev, *child; | |
113 | ||
114 | /* Walk through the children one by one */ | |
115 | ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); | |
116 | ut_assertok(device_find_first_child(bus, &dev)); | |
117 | ut_asserteq_str("c-test@5", dev->name); | |
118 | ut_assertok(device_find_next_child(&dev)); | |
119 | ut_asserteq_str("c-test@0", dev->name); | |
120 | ut_assertok(device_find_next_child(&dev)); | |
121 | ut_asserteq_str("c-test@1", dev->name); | |
122 | ut_assertok(device_find_next_child(&dev)); | |
123 | ut_asserteq_ptr(dev, NULL); | |
124 | ||
125 | /* Move to the next child without using device_find_first_child() */ | |
99175919 | 126 | ut_assertok(device_find_child_by_seq(bus, 5, &dev)); |
a8981d4f SG |
127 | ut_asserteq_str("c-test@5", dev->name); |
128 | ut_assertok(device_find_next_child(&dev)); | |
129 | ut_asserteq_str("c-test@0", dev->name); | |
130 | ||
131 | /* Try a device with no children */ | |
132 | ut_assertok(device_find_first_child(dev, &child)); | |
133 | ut_asserteq_ptr(child, NULL); | |
134 | ||
135 | return 0; | |
136 | } | |
137 | DM_TEST(dm_test_bus_children_iterators, | |
e180c2b1 | 138 | UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |
a8981d4f | 139 | |
e59f458d | 140 | /* Test that the bus can store data about each child */ |
e721b882 | 141 | static int test_bus_parent_data(struct unit_test_state *uts) |
e59f458d SG |
142 | { |
143 | struct dm_test_parent_data *parent_data; | |
144 | struct udevice *bus, *dev; | |
145 | struct uclass *uc; | |
146 | int value; | |
147 | ||
148 | ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); | |
149 | ||
150 | /* Check that parent data is allocated */ | |
99175919 | 151 | ut_assertok(device_find_child_by_seq(bus, 0, &dev)); |
bcbe3d15 | 152 | ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); |
e59f458d | 153 | ut_assertok(device_get_child_by_seq(bus, 0, &dev)); |
bcbe3d15 | 154 | parent_data = dev_get_parent_priv(dev); |
e59f458d SG |
155 | ut_assert(NULL != parent_data); |
156 | ||
157 | /* Check that it starts at 0 and goes away when device is removed */ | |
158 | parent_data->sum += 5; | |
159 | ut_asserteq(5, parent_data->sum); | |
706865af | 160 | device_remove(dev, DM_REMOVE_NORMAL); |
bcbe3d15 | 161 | ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); |
e59f458d SG |
162 | |
163 | /* Check that we can do this twice */ | |
164 | ut_assertok(device_get_child_by_seq(bus, 0, &dev)); | |
bcbe3d15 | 165 | parent_data = dev_get_parent_priv(dev); |
e59f458d SG |
166 | ut_assert(NULL != parent_data); |
167 | parent_data->sum += 5; | |
168 | ut_asserteq(5, parent_data->sum); | |
169 | ||
170 | /* Add parent data to all children */ | |
171 | ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc)); | |
172 | value = 5; | |
173 | uclass_foreach_dev(dev, uc) { | |
174 | /* Ignore these if they are not on this bus */ | |
175 | if (dev->parent != bus) { | |
bcbe3d15 | 176 | ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); |
e59f458d SG |
177 | continue; |
178 | } | |
179 | ut_assertok(device_probe(dev)); | |
bcbe3d15 | 180 | parent_data = dev_get_parent_priv(dev); |
e59f458d SG |
181 | |
182 | parent_data->sum = value; | |
183 | value += 5; | |
184 | } | |
185 | ||
186 | /* Check it is still there */ | |
187 | value = 5; | |
188 | uclass_foreach_dev(dev, uc) { | |
189 | /* Ignore these if they are not on this bus */ | |
190 | if (dev->parent != bus) | |
191 | continue; | |
bcbe3d15 | 192 | parent_data = dev_get_parent_priv(dev); |
e59f458d SG |
193 | |
194 | ut_asserteq(value, parent_data->sum); | |
195 | value += 5; | |
196 | } | |
197 | ||
198 | return 0; | |
199 | } | |
dac8db2c | 200 | /* Test that the bus can store data about each child */ |
e721b882 | 201 | static int dm_test_bus_parent_data(struct unit_test_state *uts) |
dac8db2c | 202 | { |
e721b882 | 203 | return test_bus_parent_data(uts); |
dac8db2c | 204 | } |
e180c2b1 | 205 | DM_TEST(dm_test_bus_parent_data, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |
a327dee0 | 206 | |
dac8db2c | 207 | /* As above but the size is controlled by the uclass */ |
e721b882 | 208 | static int dm_test_bus_parent_data_uclass(struct unit_test_state *uts) |
dac8db2c | 209 | { |
e23eb614 | 210 | struct driver *drv; |
dac8db2c SG |
211 | struct udevice *bus; |
212 | int size; | |
213 | int ret; | |
214 | ||
215 | /* Set the driver size to 0 so that the uclass size is used */ | |
216 | ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); | |
e23eb614 | 217 | drv = (struct driver *)bus->driver; |
41575d8e | 218 | size = drv->per_child_auto; |
9f8037ea SG |
219 | |
220 | #ifdef CONFIG_SANDBOX | |
221 | os_mprotect_allow(bus->uclass->uc_drv, sizeof(*bus->uclass->uc_drv)); | |
222 | os_mprotect_allow(drv, sizeof(*drv)); | |
223 | #endif | |
41575d8e SG |
224 | bus->uclass->uc_drv->per_child_auto = size; |
225 | drv->per_child_auto = 0; | |
e721b882 | 226 | ret = test_bus_parent_data(uts); |
dac8db2c SG |
227 | if (ret) |
228 | return ret; | |
41575d8e SG |
229 | bus->uclass->uc_drv->per_child_auto = 0; |
230 | drv->per_child_auto = size; | |
dac8db2c SG |
231 | |
232 | return 0; | |
233 | } | |
234 | DM_TEST(dm_test_bus_parent_data_uclass, | |
e180c2b1 | 235 | UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |
dac8db2c | 236 | |
a327dee0 | 237 | /* Test that the bus ops are called when a child is probed/removed */ |
e721b882 | 238 | static int dm_test_bus_parent_ops(struct unit_test_state *uts) |
a327dee0 SG |
239 | { |
240 | struct dm_test_parent_data *parent_data; | |
241 | struct udevice *bus, *dev; | |
242 | struct uclass *uc; | |
243 | ||
079ac595 | 244 | testbus_get_clear_removed(); |
a327dee0 SG |
245 | ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); |
246 | ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc)); | |
247 | ||
248 | uclass_foreach_dev(dev, uc) { | |
249 | /* Ignore these if they are not on this bus */ | |
250 | if (dev->parent != bus) | |
251 | continue; | |
bcbe3d15 | 252 | ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); |
a327dee0 SG |
253 | |
254 | ut_assertok(device_probe(dev)); | |
bcbe3d15 | 255 | parent_data = dev_get_parent_priv(dev); |
079ac595 | 256 | ut_asserteq(TEST_FLAG_CHILD_PROBED, parent_data->flag); |
a327dee0 SG |
257 | } |
258 | ||
259 | uclass_foreach_dev(dev, uc) { | |
260 | /* Ignore these if they are not on this bus */ | |
261 | if (dev->parent != bus) | |
262 | continue; | |
bcbe3d15 | 263 | parent_data = dev_get_parent_priv(dev); |
079ac595 | 264 | ut_asserteq(TEST_FLAG_CHILD_PROBED, parent_data->flag); |
706865af | 265 | ut_assertok(device_remove(dev, DM_REMOVE_NORMAL)); |
bcbe3d15 | 266 | ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); |
079ac595 | 267 | ut_asserteq_ptr(testbus_get_clear_removed(), dev); |
a327dee0 | 268 | } |
a327dee0 SG |
269 | |
270 | return 0; | |
271 | } | |
e180c2b1 | 272 | DM_TEST(dm_test_bus_parent_ops, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |
cdc133bd | 273 | |
caa4daa2 | 274 | static int test_bus_parent_plat(struct unit_test_state *uts) |
cdc133bd | 275 | { |
caa4daa2 | 276 | struct dm_test_parent_plat *plat; |
cdc133bd | 277 | struct udevice *bus, *dev; |
cdc133bd SG |
278 | |
279 | /* Check that the bus has no children */ | |
280 | ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); | |
281 | device_find_first_child(bus, &dev); | |
282 | ut_asserteq_ptr(NULL, dev); | |
283 | ||
284 | ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); | |
285 | ||
240b9320 | 286 | for (device_find_first_child(bus, &dev); |
cdc133bd SG |
287 | dev; |
288 | device_find_next_child(&dev)) { | |
289 | /* Check that platform data is allocated */ | |
caa4daa2 | 290 | plat = dev_get_parent_plat(dev); |
cdc133bd SG |
291 | ut_assert(plat != NULL); |
292 | ||
293 | /* | |
294 | * Check that it is not affected by the device being | |
295 | * probed/removed | |
296 | */ | |
297 | plat->count++; | |
298 | ut_asserteq(1, plat->count); | |
299 | device_probe(dev); | |
706865af | 300 | device_remove(dev, DM_REMOVE_NORMAL); |
cdc133bd | 301 | |
caa4daa2 | 302 | ut_asserteq_ptr(plat, dev_get_parent_plat(dev)); |
cdc133bd SG |
303 | ut_asserteq(1, plat->count); |
304 | ut_assertok(device_probe(dev)); | |
cdc133bd | 305 | } |
240b9320 | 306 | ut_asserteq(3, device_get_child_count(bus)); |
cdc133bd SG |
307 | |
308 | /* Removing the bus should also have no effect (it is still bound) */ | |
706865af | 309 | device_remove(bus, DM_REMOVE_NORMAL); |
240b9320 | 310 | for (device_find_first_child(bus, &dev); |
cdc133bd SG |
311 | dev; |
312 | device_find_next_child(&dev)) { | |
313 | /* Check that platform data is allocated */ | |
caa4daa2 | 314 | plat = dev_get_parent_plat(dev); |
cdc133bd SG |
315 | ut_assert(plat != NULL); |
316 | ut_asserteq(1, plat->count); | |
cdc133bd | 317 | } |
240b9320 | 318 | ut_asserteq(3, device_get_child_count(bus)); |
cdc133bd SG |
319 | |
320 | /* Unbind all the children */ | |
321 | do { | |
322 | device_find_first_child(bus, &dev); | |
323 | if (dev) | |
324 | device_unbind(dev); | |
325 | } while (dev); | |
326 | ||
caa4daa2 | 327 | /* Now the child plat should be removed and re-added */ |
cdc133bd | 328 | device_probe(bus); |
240b9320 | 329 | for (device_find_first_child(bus, &dev); |
cdc133bd SG |
330 | dev; |
331 | device_find_next_child(&dev)) { | |
332 | /* Check that platform data is allocated */ | |
caa4daa2 | 333 | plat = dev_get_parent_plat(dev); |
cdc133bd SG |
334 | ut_assert(plat != NULL); |
335 | ut_asserteq(0, plat->count); | |
cdc133bd | 336 | } |
240b9320 | 337 | ut_asserteq(3, device_get_child_count(bus)); |
cdc133bd SG |
338 | |
339 | return 0; | |
340 | } | |
ba8da9dc SG |
341 | |
342 | /* Test that the bus can store platform data about each child */ | |
caa4daa2 | 343 | static int dm_test_bus_parent_plat(struct unit_test_state *uts) |
ba8da9dc | 344 | { |
caa4daa2 | 345 | return test_bus_parent_plat(uts); |
ba8da9dc | 346 | } |
caa4daa2 | 347 | DM_TEST(dm_test_bus_parent_plat, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |
ba8da9dc SG |
348 | |
349 | /* As above but the size is controlled by the uclass */ | |
caa4daa2 | 350 | static int dm_test_bus_parent_plat_uclass(struct unit_test_state *uts) |
ba8da9dc SG |
351 | { |
352 | struct udevice *bus; | |
e23eb614 | 353 | struct driver *drv; |
ba8da9dc SG |
354 | int size; |
355 | int ret; | |
356 | ||
357 | /* Set the driver size to 0 so that the uclass size is used */ | |
358 | ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus)); | |
e23eb614 | 359 | drv = (struct driver *)bus->driver; |
caa4daa2 | 360 | size = drv->per_child_plat_auto; |
9f8037ea SG |
361 | #ifdef CONFIG_SANDBOX |
362 | os_mprotect_allow(bus->uclass->uc_drv, sizeof(*bus->uclass->uc_drv)); | |
363 | os_mprotect_allow(drv, sizeof(*drv)); | |
364 | #endif | |
caa4daa2 SG |
365 | bus->uclass->uc_drv->per_child_plat_auto = size; |
366 | drv->per_child_plat_auto = 0; | |
367 | ret = test_bus_parent_plat(uts); | |
ba8da9dc SG |
368 | if (ret) |
369 | return ret; | |
caa4daa2 SG |
370 | bus->uclass->uc_drv->per_child_plat_auto = 0; |
371 | drv->per_child_plat_auto = size; | |
ba8da9dc SG |
372 | |
373 | return 0; | |
374 | } | |
caa4daa2 | 375 | DM_TEST(dm_test_bus_parent_plat_uclass, |
e180c2b1 | 376 | UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |
0118ce79 SG |
377 | |
378 | /* Test that the child post_bind method is called */ | |
e721b882 | 379 | static int dm_test_bus_child_post_bind(struct unit_test_state *uts) |
0118ce79 | 380 | { |
caa4daa2 | 381 | struct dm_test_parent_plat *plat; |
0118ce79 | 382 | struct udevice *bus, *dev; |
0118ce79 SG |
383 | |
384 | ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); | |
240b9320 | 385 | for (device_find_first_child(bus, &dev); |
0118ce79 SG |
386 | dev; |
387 | device_find_next_child(&dev)) { | |
388 | /* Check that platform data is allocated */ | |
caa4daa2 | 389 | plat = dev_get_parent_plat(dev); |
0118ce79 SG |
390 | ut_assert(plat != NULL); |
391 | ut_asserteq(1, plat->bind_flag); | |
0118ce79 | 392 | } |
240b9320 | 393 | ut_asserteq(3, device_get_child_count(bus)); |
0118ce79 SG |
394 | |
395 | return 0; | |
396 | } | |
e180c2b1 | 397 | DM_TEST(dm_test_bus_child_post_bind, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |
081f2fcb SG |
398 | |
399 | /* Test that the child post_bind method is called */ | |
e721b882 | 400 | static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts) |
081f2fcb | 401 | { |
caa4daa2 | 402 | struct dm_test_parent_plat *plat; |
081f2fcb | 403 | struct udevice *bus, *dev; |
081f2fcb SG |
404 | |
405 | ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); | |
240b9320 | 406 | for (device_find_first_child(bus, &dev); |
081f2fcb SG |
407 | dev; |
408 | device_find_next_child(&dev)) { | |
409 | /* Check that platform data is allocated */ | |
caa4daa2 | 410 | plat = dev_get_parent_plat(dev); |
081f2fcb SG |
411 | ut_assert(plat != NULL); |
412 | ut_asserteq(2, plat->uclass_bind_flag); | |
081f2fcb | 413 | } |
240b9320 | 414 | ut_asserteq(3, device_get_child_count(bus)); |
081f2fcb SG |
415 | |
416 | return 0; | |
417 | } | |
418 | DM_TEST(dm_test_bus_child_post_bind_uclass, | |
e180c2b1 | 419 | UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |
83c7e434 SG |
420 | |
421 | /* | |
422 | * Test that the bus' uclass' child_pre_probe() is called before the | |
423 | * device's probe() method | |
424 | */ | |
e721b882 | 425 | static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts) |
83c7e434 SG |
426 | { |
427 | struct udevice *bus, *dev; | |
83c7e434 SG |
428 | |
429 | /* | |
430 | * See testfdt_drv_probe() which effectively checks that the uclass | |
431 | * flag is set before that method is called | |
432 | */ | |
433 | ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); | |
240b9320 | 434 | for (device_find_first_child(bus, &dev); |
83c7e434 SG |
435 | dev; |
436 | device_find_next_child(&dev)) { | |
437 | struct dm_test_priv *priv = dev_get_priv(dev); | |
438 | ||
439 | /* Check that things happened in the right order */ | |
440 | ut_asserteq_ptr(NULL, priv); | |
441 | ut_assertok(device_probe(dev)); | |
442 | ||
443 | priv = dev_get_priv(dev); | |
444 | ut_assert(priv != NULL); | |
445 | ut_asserteq(1, priv->uclass_flag); | |
446 | ut_asserteq(1, priv->uclass_total); | |
83c7e434 | 447 | } |
240b9320 | 448 | ut_asserteq(3, device_get_child_count(bus)); |
83c7e434 SG |
449 | |
450 | return 0; | |
451 | } | |
452 | DM_TEST(dm_test_bus_child_pre_probe_uclass, | |
e180c2b1 | 453 | UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |
d92878aa BM |
454 | |
455 | /* | |
456 | * Test that the bus' uclass' child_post_probe() is called after the | |
457 | * device's probe() method | |
458 | */ | |
459 | static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts) | |
460 | { | |
461 | struct udevice *bus, *dev; | |
d92878aa BM |
462 | |
463 | /* | |
464 | * See testfdt_drv_probe() which effectively initializes that | |
465 | * the uclass postp flag is set to a value | |
466 | */ | |
467 | ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); | |
240b9320 | 468 | for (device_find_first_child(bus, &dev); |
d92878aa BM |
469 | dev; |
470 | device_find_next_child(&dev)) { | |
471 | struct dm_test_priv *priv = dev_get_priv(dev); | |
472 | ||
473 | /* Check that things happened in the right order */ | |
474 | ut_asserteq_ptr(NULL, priv); | |
475 | ut_assertok(device_probe(dev)); | |
476 | ||
477 | priv = dev_get_priv(dev); | |
478 | ut_assert(priv != NULL); | |
479 | ut_asserteq(0, priv->uclass_postp); | |
d92878aa | 480 | } |
240b9320 | 481 | ut_asserteq(3, device_get_child_count(bus)); |
d92878aa BM |
482 | |
483 | return 0; | |
484 | } | |
485 | DM_TEST(dm_test_bus_child_post_probe_uclass, | |
e180c2b1 | 486 | UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |