blob: e768eab6957a62414493853fc108faaaa203076d [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass1ca7e202014-07-23 06:55:18 -06002/*
3 * Copyright (c) 2014 Google, Inc
Simon Glass1ca7e202014-07-23 06:55:18 -06004 */
5
6#include <common.h>
Simon Glass9f8037e2018-10-01 21:12:32 -06007#ifdef CONFIG_SANDBOX
Simon Glassf7ae49f2020-05-10 11:40:05 -06008#include <log.h>
Simon Glass9f8037e2018-10-01 21:12:32 -06009#include <os.h>
10#endif
Simon Glass1ca7e202014-07-23 06:55:18 -060011#include <dm.h>
Lokesh Vutla240b9322019-09-04 16:01:26 +053012#include <dm/device.h>
Simon Glasse59f4582014-07-23 06:55:20 -060013#include <dm/device-internal.h>
Simon Glass1ca7e202014-07-23 06:55:18 -060014#include <dm/test.h>
Simon Glasscdc133b2015-01-25 08:27:01 -070015#include <dm/uclass-internal.h>
Simon Glass1ca7e202014-07-23 06:55:18 -060016#include <dm/util.h>
Simon Glass0e1fad42020-07-19 10:15:37 -060017#include <test/test.h>
Joe Hershbergere721b882015-05-20 14:27:27 -050018#include <test/ut.h>
Simon Glass1ca7e202014-07-23 06:55:18 -060019
20DECLARE_GLOBAL_DATA_PTR;
21
Simon Glass1ca7e202014-07-23 06:55:18 -060022/* Test that we can probe for children */
Joe Hershbergere721b882015-05-20 14:27:27 -050023static int dm_test_bus_children(struct unit_test_state *uts)
Simon Glass1ca7e202014-07-23 06:55:18 -060024{
Jean-Jacques Hiblot88e6a602020-09-11 13:43:35 +053025 int num_devices = 9;
Simon Glass1ca7e202014-07-23 06:55:18 -060026 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
Joe Hershbergere721b882015-05-20 14:27:27 -050039 ut_assert(!dm_check_devices(uts, num_devices));
Simon Glass1ca7e202014-07-23 06:55:18 -060040
41 return 0;
42}
Simon Glasse180c2b2020-07-28 19:41:12 -060043DM_TEST(dm_test_bus_children, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass997c87b2014-07-23 06:55:19 -060044
45/* Test our functions for accessing children */
Joe Hershbergere721b882015-05-20 14:27:27 -050046static int dm_test_bus_children_funcs(struct unit_test_state *uts)
Simon Glass997c87b2014-07-23 06:55:19 -060047{
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));
Simon Glass73466df2020-12-19 10:40:10 -070058 ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED);
Simon Glass997c87b2014-07-23 06:55:19 -060059 ut_asserteq_str("c-test@5", dev->name);
60
61 /* Device with sequence number 0 should be accessible */
Simon Glass99175912020-12-16 21:20:29 -070062 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, &dev));
63 ut_assertok(device_find_child_by_seq(bus, 0, &dev));
Simon Glass73466df2020-12-19 10:40:10 -070064 ut_assert(!(dev_get_flags(dev) & DM_FLAG_ACTIVATED));
Simon Glass99175912020-12-16 21:20:29 -070065 ut_asserteq(0, device_find_child_by_seq(bus, 0, &dev));
Simon Glass997c87b2014-07-23 06:55:19 -060066 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
Simon Glass73466df2020-12-19 10:40:10 -070067 ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED);
Simon Glass99175912020-12-16 21:20:29 -070068 ut_asserteq(0, device_find_child_by_seq(bus, 0, &dev));
Simon Glass997c87b2014-07-23 06:55:19 -060069
70 /* There is no device with sequence number 2 */
Simon Glass99175912020-12-16 21:20:29 -070071 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, &dev));
72 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, &dev));
Simon Glass997c87b2014-07-23 06:55:19 -060073 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
Simon Glass298afb52017-05-18 20:09:43 -060081 return 0;
82}
Simon Glasse180c2b2020-07-28 19:41:12 -060083DM_TEST(dm_test_bus_children_funcs, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass298afb52017-05-18 20:09:43 -060084
85static 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));
Simon Glass4f414d32017-06-07 10:28:44 -060092 ut_assertnonnull(bus);
Simon Glass298afb52017-05-18 20:09:43 -060093
Simon Glass997c87b2014-07-23 06:55:19 -060094 /* Find a valid child */
95 node = fdt_path_offset(blob, "/some-bus/c-test@1");
Simon Glass298afb52017-05-18 20:09:43 -060096 ut_assert(node > 0);
Simon Glass997c87b2014-07-23 06:55:19 -060097 ut_assertok(device_find_child_by_of_offset(bus, node, &dev));
Simon Glass4f414d32017-06-07 10:28:44 -060098 ut_assertnonnull(dev);
Simon Glass73466df2020-12-19 10:40:10 -070099 ut_assert(!(dev_get_flags(dev) & DM_FLAG_ACTIVATED));
Simon Glass997c87b2014-07-23 06:55:19 -0600100 ut_assertok(device_get_child_by_of_offset(bus, node, &dev));
Simon Glass4f414d32017-06-07 10:28:44 -0600101 ut_assertnonnull(dev);
Simon Glass73466df2020-12-19 10:40:10 -0700102 ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED);
Simon Glass997c87b2014-07-23 06:55:19 -0600103
104 return 0;
105}
Simon Glass298afb52017-05-18 20:09:43 -0600106DM_TEST(dm_test_bus_children_of_offset,
Simon Glasse180c2b2020-07-28 19:41:12 -0600107 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_FLAT_TREE);
Simon Glasse59f4582014-07-23 06:55:20 -0600108
Simon Glassa8981d42014-10-13 23:41:49 -0600109/* Test that we can iterate through children */
Joe Hershbergere721b882015-05-20 14:27:27 -0500110static int dm_test_bus_children_iterators(struct unit_test_state *uts)
Simon Glassa8981d42014-10-13 23:41:49 -0600111{
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() */
Simon Glass99175912020-12-16 21:20:29 -0700126 ut_assertok(device_find_child_by_seq(bus, 5, &dev));
Simon Glassa8981d42014-10-13 23:41:49 -0600127 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}
137DM_TEST(dm_test_bus_children_iterators,
Simon Glasse180c2b2020-07-28 19:41:12 -0600138 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glassa8981d42014-10-13 23:41:49 -0600139
Simon Glasse59f4582014-07-23 06:55:20 -0600140/* Test that the bus can store data about each child */
Joe Hershbergere721b882015-05-20 14:27:27 -0500141static int test_bus_parent_data(struct unit_test_state *uts)
Simon Glasse59f4582014-07-23 06:55:20 -0600142{
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 */
Simon Glass99175912020-12-16 21:20:29 -0700151 ut_assertok(device_find_child_by_seq(bus, 0, &dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600152 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glasse59f4582014-07-23 06:55:20 -0600153 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600154 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600155 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);
Stefan Roese706865a2017-03-20 12:51:48 +0100160 device_remove(dev, DM_REMOVE_NORMAL);
Simon Glassbcbe3d12015-09-28 23:32:01 -0600161 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glasse59f4582014-07-23 06:55:20 -0600162
163 /* Check that we can do this twice */
164 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600165 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600166 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) {
Simon Glassbcbe3d12015-09-28 23:32:01 -0600176 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glasse59f4582014-07-23 06:55:20 -0600177 continue;
178 }
179 ut_assertok(device_probe(dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600180 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600181
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;
Simon Glassbcbe3d12015-09-28 23:32:01 -0600192 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600193
194 ut_asserteq(value, parent_data->sum);
195 value += 5;
196 }
197
198 return 0;
199}
Simon Glassdac8db22015-01-25 08:27:06 -0700200/* Test that the bus can store data about each child */
Joe Hershbergere721b882015-05-20 14:27:27 -0500201static int dm_test_bus_parent_data(struct unit_test_state *uts)
Simon Glassdac8db22015-01-25 08:27:06 -0700202{
Joe Hershbergere721b882015-05-20 14:27:27 -0500203 return test_bus_parent_data(uts);
Simon Glassdac8db22015-01-25 08:27:06 -0700204}
Simon Glasse180c2b2020-07-28 19:41:12 -0600205DM_TEST(dm_test_bus_parent_data, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glassa327dee2014-07-23 06:55:21 -0600206
Simon Glassdac8db22015-01-25 08:27:06 -0700207/* As above but the size is controlled by the uclass */
Joe Hershbergere721b882015-05-20 14:27:27 -0500208static int dm_test_bus_parent_data_uclass(struct unit_test_state *uts)
Simon Glassdac8db22015-01-25 08:27:06 -0700209{
Simon Glasse23eb612015-03-25 12:21:51 -0600210 struct driver *drv;
Simon Glassdac8db22015-01-25 08:27:06 -0700211 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));
Simon Glasse23eb612015-03-25 12:21:51 -0600217 drv = (struct driver *)bus->driver;
Simon Glass41575d82020-12-03 16:55:17 -0700218 size = drv->per_child_auto;
Simon Glass9f8037e2018-10-01 21:12:32 -0600219
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
Simon Glass41575d82020-12-03 16:55:17 -0700224 bus->uclass->uc_drv->per_child_auto = size;
225 drv->per_child_auto = 0;
Joe Hershbergere721b882015-05-20 14:27:27 -0500226 ret = test_bus_parent_data(uts);
Simon Glassdac8db22015-01-25 08:27:06 -0700227 if (ret)
228 return ret;
Simon Glass41575d82020-12-03 16:55:17 -0700229 bus->uclass->uc_drv->per_child_auto = 0;
230 drv->per_child_auto = size;
Simon Glassdac8db22015-01-25 08:27:06 -0700231
232 return 0;
233}
234DM_TEST(dm_test_bus_parent_data_uclass,
Simon Glasse180c2b2020-07-28 19:41:12 -0600235 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glassdac8db22015-01-25 08:27:06 -0700236
Simon Glassa327dee2014-07-23 06:55:21 -0600237/* Test that the bus ops are called when a child is probed/removed */
Joe Hershbergere721b882015-05-20 14:27:27 -0500238static int dm_test_bus_parent_ops(struct unit_test_state *uts)
Simon Glassa327dee2014-07-23 06:55:21 -0600239{
240 struct dm_test_parent_data *parent_data;
241 struct udevice *bus, *dev;
242 struct uclass *uc;
243
Simon Glass079ac592020-12-23 08:11:18 -0700244 testbus_get_clear_removed();
Simon Glassa327dee2014-07-23 06:55:21 -0600245 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;
Simon Glassbcbe3d12015-09-28 23:32:01 -0600252 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glassa327dee2014-07-23 06:55:21 -0600253
254 ut_assertok(device_probe(dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600255 parent_data = dev_get_parent_priv(dev);
Simon Glass079ac592020-12-23 08:11:18 -0700256 ut_asserteq(TEST_FLAG_CHILD_PROBED, parent_data->flag);
Simon Glassa327dee2014-07-23 06:55:21 -0600257 }
258
259 uclass_foreach_dev(dev, uc) {
260 /* Ignore these if they are not on this bus */
261 if (dev->parent != bus)
262 continue;
Simon Glassbcbe3d12015-09-28 23:32:01 -0600263 parent_data = dev_get_parent_priv(dev);
Simon Glass079ac592020-12-23 08:11:18 -0700264 ut_asserteq(TEST_FLAG_CHILD_PROBED, parent_data->flag);
Stefan Roese706865a2017-03-20 12:51:48 +0100265 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600266 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glass079ac592020-12-23 08:11:18 -0700267 ut_asserteq_ptr(testbus_get_clear_removed(), dev);
Simon Glassa327dee2014-07-23 06:55:21 -0600268 }
Simon Glassa327dee2014-07-23 06:55:21 -0600269
270 return 0;
271}
Simon Glasse180c2b2020-07-28 19:41:12 -0600272DM_TEST(dm_test_bus_parent_ops, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glasscdc133b2015-01-25 08:27:01 -0700273
Simon Glasscaa4daa2020-12-03 16:55:18 -0700274static int test_bus_parent_plat(struct unit_test_state *uts)
Simon Glasscdc133b2015-01-25 08:27:01 -0700275{
Simon Glasscaa4daa2020-12-03 16:55:18 -0700276 struct dm_test_parent_plat *plat;
Simon Glasscdc133b2015-01-25 08:27:01 -0700277 struct udevice *bus, *dev;
Simon Glasscdc133b2015-01-25 08:27:01 -0700278
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
Lokesh Vutla240b9322019-09-04 16:01:26 +0530286 for (device_find_first_child(bus, &dev);
Simon Glasscdc133b2015-01-25 08:27:01 -0700287 dev;
288 device_find_next_child(&dev)) {
289 /* Check that platform data is allocated */
Simon Glasscaa4daa2020-12-03 16:55:18 -0700290 plat = dev_get_parent_plat(dev);
Simon Glasscdc133b2015-01-25 08:27:01 -0700291 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);
Stefan Roese706865a2017-03-20 12:51:48 +0100300 device_remove(dev, DM_REMOVE_NORMAL);
Simon Glasscdc133b2015-01-25 08:27:01 -0700301
Simon Glasscaa4daa2020-12-03 16:55:18 -0700302 ut_asserteq_ptr(plat, dev_get_parent_plat(dev));
Simon Glasscdc133b2015-01-25 08:27:01 -0700303 ut_asserteq(1, plat->count);
304 ut_assertok(device_probe(dev));
Simon Glasscdc133b2015-01-25 08:27:01 -0700305 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530306 ut_asserteq(3, device_get_child_count(bus));
Simon Glasscdc133b2015-01-25 08:27:01 -0700307
308 /* Removing the bus should also have no effect (it is still bound) */
Stefan Roese706865a2017-03-20 12:51:48 +0100309 device_remove(bus, DM_REMOVE_NORMAL);
Lokesh Vutla240b9322019-09-04 16:01:26 +0530310 for (device_find_first_child(bus, &dev);
Simon Glasscdc133b2015-01-25 08:27:01 -0700311 dev;
312 device_find_next_child(&dev)) {
313 /* Check that platform data is allocated */
Simon Glasscaa4daa2020-12-03 16:55:18 -0700314 plat = dev_get_parent_plat(dev);
Simon Glasscdc133b2015-01-25 08:27:01 -0700315 ut_assert(plat != NULL);
316 ut_asserteq(1, plat->count);
Simon Glasscdc133b2015-01-25 08:27:01 -0700317 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530318 ut_asserteq(3, device_get_child_count(bus));
Simon Glasscdc133b2015-01-25 08:27:01 -0700319
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
Simon Glasscaa4daa2020-12-03 16:55:18 -0700327 /* Now the child plat should be removed and re-added */
Simon Glasscdc133b2015-01-25 08:27:01 -0700328 device_probe(bus);
Lokesh Vutla240b9322019-09-04 16:01:26 +0530329 for (device_find_first_child(bus, &dev);
Simon Glasscdc133b2015-01-25 08:27:01 -0700330 dev;
331 device_find_next_child(&dev)) {
332 /* Check that platform data is allocated */
Simon Glasscaa4daa2020-12-03 16:55:18 -0700333 plat = dev_get_parent_plat(dev);
Simon Glasscdc133b2015-01-25 08:27:01 -0700334 ut_assert(plat != NULL);
335 ut_asserteq(0, plat->count);
Simon Glasscdc133b2015-01-25 08:27:01 -0700336 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530337 ut_asserteq(3, device_get_child_count(bus));
Simon Glasscdc133b2015-01-25 08:27:01 -0700338
339 return 0;
340}
Simon Glassba8da9d2015-01-25 08:27:02 -0700341
342/* Test that the bus can store platform data about each child */
Simon Glasscaa4daa2020-12-03 16:55:18 -0700343static int dm_test_bus_parent_plat(struct unit_test_state *uts)
Simon Glassba8da9d2015-01-25 08:27:02 -0700344{
Simon Glasscaa4daa2020-12-03 16:55:18 -0700345 return test_bus_parent_plat(uts);
Simon Glassba8da9d2015-01-25 08:27:02 -0700346}
Simon Glasscaa4daa2020-12-03 16:55:18 -0700347DM_TEST(dm_test_bus_parent_plat, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glassba8da9d2015-01-25 08:27:02 -0700348
349/* As above but the size is controlled by the uclass */
Simon Glasscaa4daa2020-12-03 16:55:18 -0700350static int dm_test_bus_parent_plat_uclass(struct unit_test_state *uts)
Simon Glassba8da9d2015-01-25 08:27:02 -0700351{
352 struct udevice *bus;
Simon Glasse23eb612015-03-25 12:21:51 -0600353 struct driver *drv;
Simon Glassba8da9d2015-01-25 08:27:02 -0700354 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));
Simon Glasse23eb612015-03-25 12:21:51 -0600359 drv = (struct driver *)bus->driver;
Simon Glasscaa4daa2020-12-03 16:55:18 -0700360 size = drv->per_child_plat_auto;
Simon Glass9f8037e2018-10-01 21:12:32 -0600361#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
Simon Glasscaa4daa2020-12-03 16:55:18 -0700365 bus->uclass->uc_drv->per_child_plat_auto = size;
366 drv->per_child_plat_auto = 0;
367 ret = test_bus_parent_plat(uts);
Simon Glassba8da9d2015-01-25 08:27:02 -0700368 if (ret)
369 return ret;
Simon Glasscaa4daa2020-12-03 16:55:18 -0700370 bus->uclass->uc_drv->per_child_plat_auto = 0;
371 drv->per_child_plat_auto = size;
Simon Glassba8da9d2015-01-25 08:27:02 -0700372
373 return 0;
374}
Simon Glasscaa4daa2020-12-03 16:55:18 -0700375DM_TEST(dm_test_bus_parent_plat_uclass,
Simon Glasse180c2b2020-07-28 19:41:12 -0600376 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass0118ce72015-01-25 08:27:03 -0700377
378/* Test that the child post_bind method is called */
Joe Hershbergere721b882015-05-20 14:27:27 -0500379static int dm_test_bus_child_post_bind(struct unit_test_state *uts)
Simon Glass0118ce72015-01-25 08:27:03 -0700380{
Simon Glasscaa4daa2020-12-03 16:55:18 -0700381 struct dm_test_parent_plat *plat;
Simon Glass0118ce72015-01-25 08:27:03 -0700382 struct udevice *bus, *dev;
Simon Glass0118ce72015-01-25 08:27:03 -0700383
384 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
Lokesh Vutla240b9322019-09-04 16:01:26 +0530385 for (device_find_first_child(bus, &dev);
Simon Glass0118ce72015-01-25 08:27:03 -0700386 dev;
387 device_find_next_child(&dev)) {
388 /* Check that platform data is allocated */
Simon Glasscaa4daa2020-12-03 16:55:18 -0700389 plat = dev_get_parent_plat(dev);
Simon Glass0118ce72015-01-25 08:27:03 -0700390 ut_assert(plat != NULL);
391 ut_asserteq(1, plat->bind_flag);
Simon Glass0118ce72015-01-25 08:27:03 -0700392 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530393 ut_asserteq(3, device_get_child_count(bus));
Simon Glass0118ce72015-01-25 08:27:03 -0700394
395 return 0;
396}
Simon Glasse180c2b2020-07-28 19:41:12 -0600397DM_TEST(dm_test_bus_child_post_bind, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass081f2fc2015-01-25 08:27:08 -0700398
399/* Test that the child post_bind method is called */
Joe Hershbergere721b882015-05-20 14:27:27 -0500400static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts)
Simon Glass081f2fc2015-01-25 08:27:08 -0700401{
Simon Glasscaa4daa2020-12-03 16:55:18 -0700402 struct dm_test_parent_plat *plat;
Simon Glass081f2fc2015-01-25 08:27:08 -0700403 struct udevice *bus, *dev;
Simon Glass081f2fc2015-01-25 08:27:08 -0700404
405 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
Lokesh Vutla240b9322019-09-04 16:01:26 +0530406 for (device_find_first_child(bus, &dev);
Simon Glass081f2fc2015-01-25 08:27:08 -0700407 dev;
408 device_find_next_child(&dev)) {
409 /* Check that platform data is allocated */
Simon Glasscaa4daa2020-12-03 16:55:18 -0700410 plat = dev_get_parent_plat(dev);
Simon Glass081f2fc2015-01-25 08:27:08 -0700411 ut_assert(plat != NULL);
412 ut_asserteq(2, plat->uclass_bind_flag);
Simon Glass081f2fc2015-01-25 08:27:08 -0700413 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530414 ut_asserteq(3, device_get_child_count(bus));
Simon Glass081f2fc2015-01-25 08:27:08 -0700415
416 return 0;
417}
418DM_TEST(dm_test_bus_child_post_bind_uclass,
Simon Glasse180c2b2020-07-28 19:41:12 -0600419 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass83c7e432015-01-25 08:27:10 -0700420
421/*
422 * Test that the bus' uclass' child_pre_probe() is called before the
423 * device's probe() method
424 */
Joe Hershbergere721b882015-05-20 14:27:27 -0500425static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
Simon Glass83c7e432015-01-25 08:27:10 -0700426{
427 struct udevice *bus, *dev;
Simon Glass83c7e432015-01-25 08:27:10 -0700428
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));
Lokesh Vutla240b9322019-09-04 16:01:26 +0530434 for (device_find_first_child(bus, &dev);
Simon Glass83c7e432015-01-25 08:27:10 -0700435 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);
Simon Glass83c7e432015-01-25 08:27:10 -0700447 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530448 ut_asserteq(3, device_get_child_count(bus));
Simon Glass83c7e432015-01-25 08:27:10 -0700449
450 return 0;
451}
452DM_TEST(dm_test_bus_child_pre_probe_uclass,
Simon Glasse180c2b2020-07-28 19:41:12 -0600453 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Bin Mengd92878a2018-10-15 02:20:58 -0700454
455/*
456 * Test that the bus' uclass' child_post_probe() is called after the
457 * device's probe() method
458 */
459static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts)
460{
461 struct udevice *bus, *dev;
Bin Mengd92878a2018-10-15 02:20:58 -0700462
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));
Lokesh Vutla240b9322019-09-04 16:01:26 +0530468 for (device_find_first_child(bus, &dev);
Bin Mengd92878a2018-10-15 02:20:58 -0700469 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);
Bin Mengd92878a2018-10-15 02:20:58 -0700480 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530481 ut_asserteq(3, device_get_child_count(bus));
Bin Mengd92878a2018-10-15 02:20:58 -0700482
483 return 0;
484}
485DM_TEST(dm_test_bus_child_post_probe_uclass,
Simon Glasse180c2b2020-07-28 19:41:12 -0600486 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);