blob: 9e81b1da1f07596111e909c52e6d0af5dd416b0f [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass40717422014-07-23 06:55:18 -06002/*
3 * Copyright (c) 2014 Google, Inc
Simon Glass40717422014-07-23 06:55:18 -06004 */
5
6#include <common.h>
Simon Glass4e766c22018-10-01 21:12:32 -06007#ifdef CONFIG_SANDBOX
Simon Glass0f2af882020-05-10 11:40:05 -06008#include <log.h>
Simon Glass4e766c22018-10-01 21:12:32 -06009#include <os.h>
10#endif
Simon Glass40717422014-07-23 06:55:18 -060011#include <dm.h>
Lokesh Vutlafa45a082019-09-04 16:01:26 +053012#include <dm/device.h>
Simon Glass60d971b2014-07-23 06:55:20 -060013#include <dm/device-internal.h>
Simon Glass40717422014-07-23 06:55:18 -060014#include <dm/test.h>
Simon Glass11b61732015-01-25 08:27:01 -070015#include <dm/uclass-internal.h>
Simon Glass40717422014-07-23 06:55:18 -060016#include <dm/util.h>
Simon Glass75c4d412020-07-19 10:15:37 -060017#include <test/test.h>
Joe Hershberger3a77be52015-05-20 14:27:27 -050018#include <test/ut.h>
Simon Glass40717422014-07-23 06:55:18 -060019
20DECLARE_GLOBAL_DATA_PTR;
21
Simon Glass71fa5b42020-12-03 16:55:18 -070022struct dm_test_parent_plat {
Simon Glass11b61732015-01-25 08:27:01 -070023 int count;
Simon Glassa4a51a02015-01-25 08:27:03 -070024 int bind_flag;
Simon Glassf4c9b3e2015-01-25 08:27:08 -070025 int uclass_bind_flag;
Simon Glass11b61732015-01-25 08:27:01 -070026};
27
Simon Glassd45560d2014-07-23 06:55:21 -060028enum {
29 FLAG_CHILD_PROBED = 10,
30 FLAG_CHILD_REMOVED = -7,
31};
32
33static struct dm_test_state *test_state;
34
Simon Glass40717422014-07-23 06:55:18 -060035static int testbus_drv_probe(struct udevice *dev)
36{
Simon Glass09128c52016-07-05 17:10:09 -060037 return dm_scan_fdt_dev(dev);
Simon Glass40717422014-07-23 06:55:18 -060038}
39
Simon Glassa4a51a02015-01-25 08:27:03 -070040static int testbus_child_post_bind(struct udevice *dev)
41{
Simon Glass71fa5b42020-12-03 16:55:18 -070042 struct dm_test_parent_plat *plat;
Simon Glassa4a51a02015-01-25 08:27:03 -070043
Simon Glass71fa5b42020-12-03 16:55:18 -070044 plat = dev_get_parent_plat(dev);
Simon Glassa4a51a02015-01-25 08:27:03 -070045 plat->bind_flag = 1;
Simon Glassf4c9b3e2015-01-25 08:27:08 -070046 plat->uclass_bind_flag = 2;
Simon Glassa4a51a02015-01-25 08:27:03 -070047
48 return 0;
49}
50
Simon Glassd45560d2014-07-23 06:55:21 -060051static int testbus_child_pre_probe(struct udevice *dev)
52{
Simon Glassde44acf2015-09-28 23:32:01 -060053 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
Simon Glassd45560d2014-07-23 06:55:21 -060054
55 parent_data->flag += FLAG_CHILD_PROBED;
56
57 return 0;
58}
59
Simon Glass5104b982015-01-25 08:27:10 -070060static int testbus_child_pre_probe_uclass(struct udevice *dev)
61{
62 struct dm_test_priv *priv = dev_get_priv(dev);
63
64 priv->uclass_flag++;
65
66 return 0;
67}
68
Bin Mengd9bad172018-10-15 02:20:58 -070069static int testbus_child_post_probe_uclass(struct udevice *dev)
70{
71 struct dm_test_priv *priv = dev_get_priv(dev);
72
73 priv->uclass_postp++;
74
75 return 0;
76}
77
Simon Glassd45560d2014-07-23 06:55:21 -060078static int testbus_child_post_remove(struct udevice *dev)
79{
Simon Glassde44acf2015-09-28 23:32:01 -060080 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
Simon Glassd45560d2014-07-23 06:55:21 -060081 struct dm_test_state *dms = test_state;
82
83 parent_data->flag += FLAG_CHILD_REMOVED;
84 if (dms)
85 dms->removed = dev;
86
87 return 0;
88}
89
Simon Glass40717422014-07-23 06:55:18 -060090static const struct udevice_id testbus_ids[] = {
91 {
92 .compatible = "denx,u-boot-test-bus",
93 .data = DM_TEST_TYPE_FIRST },
94 { }
95};
96
97U_BOOT_DRIVER(testbus_drv) = {
98 .name = "testbus_drv",
99 .of_match = testbus_ids,
100 .id = UCLASS_TEST_BUS,
101 .probe = testbus_drv_probe,
Simon Glassa4a51a02015-01-25 08:27:03 -0700102 .child_post_bind = testbus_child_post_bind,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700103 .priv_auto = sizeof(struct dm_test_priv),
Simon Glass71fa5b42020-12-03 16:55:18 -0700104 .plat_auto = sizeof(struct dm_test_pdata),
Simon Glass8a2b47f2020-12-03 16:55:17 -0700105 .per_child_auto = sizeof(struct dm_test_parent_data),
Simon Glass33b2efb2020-12-03 16:55:22 -0700106 .per_child_plat_auto = sizeof(struct dm_test_parent_plat),
Simon Glassd45560d2014-07-23 06:55:21 -0600107 .child_pre_probe = testbus_child_pre_probe,
108 .child_post_remove = testbus_child_post_remove,
Simon Glass40717422014-07-23 06:55:18 -0600109};
110
111UCLASS_DRIVER(testbus) = {
112 .name = "testbus",
113 .id = UCLASS_TEST_BUS,
Simon Glass0ccb0972015-01-25 08:27:05 -0700114 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glass5104b982015-01-25 08:27:10 -0700115 .child_pre_probe = testbus_child_pre_probe_uclass,
Bin Mengd9bad172018-10-15 02:20:58 -0700116 .child_post_probe = testbus_child_post_probe_uclass,
Simon Glass40717422014-07-23 06:55:18 -0600117};
118
119/* Test that we can probe for children */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500120static int dm_test_bus_children(struct unit_test_state *uts)
Simon Glass40717422014-07-23 06:55:18 -0600121{
Jean-Jacques Hiblot73873402020-09-11 13:43:35 +0530122 int num_devices = 9;
Simon Glass40717422014-07-23 06:55:18 -0600123 struct udevice *bus;
124 struct uclass *uc;
125
126 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
127 ut_asserteq(num_devices, list_count_items(&uc->dev_head));
128
129 /* Probe the bus, which should yield 3 more devices */
130 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
131 num_devices += 3;
132
133 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
134 ut_asserteq(num_devices, list_count_items(&uc->dev_head));
135
Joe Hershberger3a77be52015-05-20 14:27:27 -0500136 ut_assert(!dm_check_devices(uts, num_devices));
Simon Glass40717422014-07-23 06:55:18 -0600137
138 return 0;
139}
Simon Glass974dccd2020-07-28 19:41:12 -0600140DM_TEST(dm_test_bus_children, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass48d4e292014-07-23 06:55:19 -0600141
142/* Test our functions for accessing children */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500143static int dm_test_bus_children_funcs(struct unit_test_state *uts)
Simon Glass48d4e292014-07-23 06:55:19 -0600144{
145 const void *blob = gd->fdt_blob;
146 struct udevice *bus, *dev;
147 int node;
148
149 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
150
151 /* device_get_child() */
152 ut_assertok(device_get_child(bus, 0, &dev));
153 ut_asserteq(-ENODEV, device_get_child(bus, 4, &dev));
154 ut_assertok(device_get_child_by_seq(bus, 5, &dev));
155 ut_assert(dev->flags & DM_FLAG_ACTIVATED);
156 ut_asserteq_str("c-test@5", dev->name);
157
158 /* Device with sequence number 0 should be accessible */
159 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, true, &dev));
160 ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
161 ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
162 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 0, false, &dev));
163 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
164 ut_assert(dev->flags & DM_FLAG_ACTIVATED);
165
166 /* There is no device with sequence number 2 */
167 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, false, &dev));
168 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, true, &dev));
169 ut_asserteq(-ENODEV, device_get_child_by_seq(bus, 2, &dev));
170
171 /* Looking for something that is not a child */
172 node = fdt_path_offset(blob, "/junk");
173 ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
174 node = fdt_path_offset(blob, "/d-test");
175 ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
176
Simon Glass9b4057a2017-05-18 20:09:43 -0600177 return 0;
178}
Simon Glass974dccd2020-07-28 19:41:12 -0600179DM_TEST(dm_test_bus_children_funcs, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass9b4057a2017-05-18 20:09:43 -0600180
181static int dm_test_bus_children_of_offset(struct unit_test_state *uts)
182{
183 const void *blob = gd->fdt_blob;
184 struct udevice *bus, *dev;
185 int node;
186
187 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
Simon Glassac855522017-06-07 10:28:44 -0600188 ut_assertnonnull(bus);
Simon Glass9b4057a2017-05-18 20:09:43 -0600189
Simon Glass48d4e292014-07-23 06:55:19 -0600190 /* Find a valid child */
191 node = fdt_path_offset(blob, "/some-bus/c-test@1");
Simon Glass9b4057a2017-05-18 20:09:43 -0600192 ut_assert(node > 0);
Simon Glass48d4e292014-07-23 06:55:19 -0600193 ut_assertok(device_find_child_by_of_offset(bus, node, &dev));
Simon Glassac855522017-06-07 10:28:44 -0600194 ut_assertnonnull(dev);
Simon Glass48d4e292014-07-23 06:55:19 -0600195 ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
196 ut_assertok(device_get_child_by_of_offset(bus, node, &dev));
Simon Glassac855522017-06-07 10:28:44 -0600197 ut_assertnonnull(dev);
Simon Glass48d4e292014-07-23 06:55:19 -0600198 ut_assert(dev->flags & DM_FLAG_ACTIVATED);
199
200 return 0;
201}
Simon Glass9b4057a2017-05-18 20:09:43 -0600202DM_TEST(dm_test_bus_children_of_offset,
Simon Glass974dccd2020-07-28 19:41:12 -0600203 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_FLAT_TREE);
Simon Glass60d971b2014-07-23 06:55:20 -0600204
Simon Glass44da7352014-10-13 23:41:49 -0600205/* Test that we can iterate through children */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500206static int dm_test_bus_children_iterators(struct unit_test_state *uts)
Simon Glass44da7352014-10-13 23:41:49 -0600207{
208 struct udevice *bus, *dev, *child;
209
210 /* Walk through the children one by one */
211 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
212 ut_assertok(device_find_first_child(bus, &dev));
213 ut_asserteq_str("c-test@5", dev->name);
214 ut_assertok(device_find_next_child(&dev));
215 ut_asserteq_str("c-test@0", dev->name);
216 ut_assertok(device_find_next_child(&dev));
217 ut_asserteq_str("c-test@1", dev->name);
218 ut_assertok(device_find_next_child(&dev));
219 ut_asserteq_ptr(dev, NULL);
220
221 /* Move to the next child without using device_find_first_child() */
222 ut_assertok(device_find_child_by_seq(bus, 5, true, &dev));
223 ut_asserteq_str("c-test@5", dev->name);
224 ut_assertok(device_find_next_child(&dev));
225 ut_asserteq_str("c-test@0", dev->name);
226
227 /* Try a device with no children */
228 ut_assertok(device_find_first_child(dev, &child));
229 ut_asserteq_ptr(child, NULL);
230
231 return 0;
232}
233DM_TEST(dm_test_bus_children_iterators,
Simon Glass974dccd2020-07-28 19:41:12 -0600234 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass44da7352014-10-13 23:41:49 -0600235
Simon Glass60d971b2014-07-23 06:55:20 -0600236/* Test that the bus can store data about each child */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500237static int test_bus_parent_data(struct unit_test_state *uts)
Simon Glass60d971b2014-07-23 06:55:20 -0600238{
239 struct dm_test_parent_data *parent_data;
240 struct udevice *bus, *dev;
241 struct uclass *uc;
242 int value;
243
244 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
245
246 /* Check that parent data is allocated */
247 ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
Simon Glassde44acf2015-09-28 23:32:01 -0600248 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glass60d971b2014-07-23 06:55:20 -0600249 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
Simon Glassde44acf2015-09-28 23:32:01 -0600250 parent_data = dev_get_parent_priv(dev);
Simon Glass60d971b2014-07-23 06:55:20 -0600251 ut_assert(NULL != parent_data);
252
253 /* Check that it starts at 0 and goes away when device is removed */
254 parent_data->sum += 5;
255 ut_asserteq(5, parent_data->sum);
Stefan Roese80b5bc92017-03-20 12:51:48 +0100256 device_remove(dev, DM_REMOVE_NORMAL);
Simon Glassde44acf2015-09-28 23:32:01 -0600257 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glass60d971b2014-07-23 06:55:20 -0600258
259 /* Check that we can do this twice */
260 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
Simon Glassde44acf2015-09-28 23:32:01 -0600261 parent_data = dev_get_parent_priv(dev);
Simon Glass60d971b2014-07-23 06:55:20 -0600262 ut_assert(NULL != parent_data);
263 parent_data->sum += 5;
264 ut_asserteq(5, parent_data->sum);
265
266 /* Add parent data to all children */
267 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
268 value = 5;
269 uclass_foreach_dev(dev, uc) {
270 /* Ignore these if they are not on this bus */
271 if (dev->parent != bus) {
Simon Glassde44acf2015-09-28 23:32:01 -0600272 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glass60d971b2014-07-23 06:55:20 -0600273 continue;
274 }
275 ut_assertok(device_probe(dev));
Simon Glassde44acf2015-09-28 23:32:01 -0600276 parent_data = dev_get_parent_priv(dev);
Simon Glass60d971b2014-07-23 06:55:20 -0600277
278 parent_data->sum = value;
279 value += 5;
280 }
281
282 /* Check it is still there */
283 value = 5;
284 uclass_foreach_dev(dev, uc) {
285 /* Ignore these if they are not on this bus */
286 if (dev->parent != bus)
287 continue;
Simon Glassde44acf2015-09-28 23:32:01 -0600288 parent_data = dev_get_parent_priv(dev);
Simon Glass60d971b2014-07-23 06:55:20 -0600289
290 ut_asserteq(value, parent_data->sum);
291 value += 5;
292 }
293
294 return 0;
295}
Simon Glassc23b4282015-01-25 08:27:06 -0700296/* Test that the bus can store data about each child */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500297static int dm_test_bus_parent_data(struct unit_test_state *uts)
Simon Glassc23b4282015-01-25 08:27:06 -0700298{
Joe Hershberger3a77be52015-05-20 14:27:27 -0500299 return test_bus_parent_data(uts);
Simon Glassc23b4282015-01-25 08:27:06 -0700300}
Simon Glass974dccd2020-07-28 19:41:12 -0600301DM_TEST(dm_test_bus_parent_data, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glassd45560d2014-07-23 06:55:21 -0600302
Simon Glassc23b4282015-01-25 08:27:06 -0700303/* As above but the size is controlled by the uclass */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500304static int dm_test_bus_parent_data_uclass(struct unit_test_state *uts)
Simon Glassc23b4282015-01-25 08:27:06 -0700305{
Simon Glass2410d882015-03-25 12:21:51 -0600306 struct driver *drv;
Simon Glassc23b4282015-01-25 08:27:06 -0700307 struct udevice *bus;
308 int size;
309 int ret;
310
311 /* Set the driver size to 0 so that the uclass size is used */
312 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
Simon Glass2410d882015-03-25 12:21:51 -0600313 drv = (struct driver *)bus->driver;
Simon Glass8a2b47f2020-12-03 16:55:17 -0700314 size = drv->per_child_auto;
Simon Glass4e766c22018-10-01 21:12:32 -0600315
316#ifdef CONFIG_SANDBOX
317 os_mprotect_allow(bus->uclass->uc_drv, sizeof(*bus->uclass->uc_drv));
318 os_mprotect_allow(drv, sizeof(*drv));
319#endif
Simon Glass8a2b47f2020-12-03 16:55:17 -0700320 bus->uclass->uc_drv->per_child_auto = size;
321 drv->per_child_auto = 0;
Joe Hershberger3a77be52015-05-20 14:27:27 -0500322 ret = test_bus_parent_data(uts);
Simon Glassc23b4282015-01-25 08:27:06 -0700323 if (ret)
324 return ret;
Simon Glass8a2b47f2020-12-03 16:55:17 -0700325 bus->uclass->uc_drv->per_child_auto = 0;
326 drv->per_child_auto = size;
Simon Glassc23b4282015-01-25 08:27:06 -0700327
328 return 0;
329}
330DM_TEST(dm_test_bus_parent_data_uclass,
Simon Glass974dccd2020-07-28 19:41:12 -0600331 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glassc23b4282015-01-25 08:27:06 -0700332
Simon Glassd45560d2014-07-23 06:55:21 -0600333/* Test that the bus ops are called when a child is probed/removed */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500334static int dm_test_bus_parent_ops(struct unit_test_state *uts)
Simon Glassd45560d2014-07-23 06:55:21 -0600335{
336 struct dm_test_parent_data *parent_data;
Joe Hershberger3a77be52015-05-20 14:27:27 -0500337 struct dm_test_state *dms = uts->priv;
Simon Glassd45560d2014-07-23 06:55:21 -0600338 struct udevice *bus, *dev;
339 struct uclass *uc;
340
341 test_state = dms;
342 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
343 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
344
345 uclass_foreach_dev(dev, uc) {
346 /* Ignore these if they are not on this bus */
347 if (dev->parent != bus)
348 continue;
Simon Glassde44acf2015-09-28 23:32:01 -0600349 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glassd45560d2014-07-23 06:55:21 -0600350
351 ut_assertok(device_probe(dev));
Simon Glassde44acf2015-09-28 23:32:01 -0600352 parent_data = dev_get_parent_priv(dev);
Simon Glassd45560d2014-07-23 06:55:21 -0600353 ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
354 }
355
356 uclass_foreach_dev(dev, uc) {
357 /* Ignore these if they are not on this bus */
358 if (dev->parent != bus)
359 continue;
Simon Glassde44acf2015-09-28 23:32:01 -0600360 parent_data = dev_get_parent_priv(dev);
Simon Glassd45560d2014-07-23 06:55:21 -0600361 ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
Stefan Roese80b5bc92017-03-20 12:51:48 +0100362 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassde44acf2015-09-28 23:32:01 -0600363 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glassd45560d2014-07-23 06:55:21 -0600364 ut_asserteq_ptr(dms->removed, dev);
365 }
366 test_state = NULL;
367
368 return 0;
369}
Simon Glass974dccd2020-07-28 19:41:12 -0600370DM_TEST(dm_test_bus_parent_ops, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass11b61732015-01-25 08:27:01 -0700371
Simon Glass71fa5b42020-12-03 16:55:18 -0700372static int test_bus_parent_plat(struct unit_test_state *uts)
Simon Glass11b61732015-01-25 08:27:01 -0700373{
Simon Glass71fa5b42020-12-03 16:55:18 -0700374 struct dm_test_parent_plat *plat;
Simon Glass11b61732015-01-25 08:27:01 -0700375 struct udevice *bus, *dev;
Simon Glass11b61732015-01-25 08:27:01 -0700376
377 /* Check that the bus has no children */
378 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
379 device_find_first_child(bus, &dev);
380 ut_asserteq_ptr(NULL, dev);
381
382 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
383
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530384 for (device_find_first_child(bus, &dev);
Simon Glass11b61732015-01-25 08:27:01 -0700385 dev;
386 device_find_next_child(&dev)) {
387 /* Check that platform data is allocated */
Simon Glass71fa5b42020-12-03 16:55:18 -0700388 plat = dev_get_parent_plat(dev);
Simon Glass11b61732015-01-25 08:27:01 -0700389 ut_assert(plat != NULL);
390
391 /*
392 * Check that it is not affected by the device being
393 * probed/removed
394 */
395 plat->count++;
396 ut_asserteq(1, plat->count);
397 device_probe(dev);
Stefan Roese80b5bc92017-03-20 12:51:48 +0100398 device_remove(dev, DM_REMOVE_NORMAL);
Simon Glass11b61732015-01-25 08:27:01 -0700399
Simon Glass71fa5b42020-12-03 16:55:18 -0700400 ut_asserteq_ptr(plat, dev_get_parent_plat(dev));
Simon Glass11b61732015-01-25 08:27:01 -0700401 ut_asserteq(1, plat->count);
402 ut_assertok(device_probe(dev));
Simon Glass11b61732015-01-25 08:27:01 -0700403 }
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530404 ut_asserteq(3, device_get_child_count(bus));
Simon Glass11b61732015-01-25 08:27:01 -0700405
406 /* Removing the bus should also have no effect (it is still bound) */
Stefan Roese80b5bc92017-03-20 12:51:48 +0100407 device_remove(bus, DM_REMOVE_NORMAL);
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530408 for (device_find_first_child(bus, &dev);
Simon Glass11b61732015-01-25 08:27:01 -0700409 dev;
410 device_find_next_child(&dev)) {
411 /* Check that platform data is allocated */
Simon Glass71fa5b42020-12-03 16:55:18 -0700412 plat = dev_get_parent_plat(dev);
Simon Glass11b61732015-01-25 08:27:01 -0700413 ut_assert(plat != NULL);
414 ut_asserteq(1, plat->count);
Simon Glass11b61732015-01-25 08:27:01 -0700415 }
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530416 ut_asserteq(3, device_get_child_count(bus));
Simon Glass11b61732015-01-25 08:27:01 -0700417
418 /* Unbind all the children */
419 do {
420 device_find_first_child(bus, &dev);
421 if (dev)
422 device_unbind(dev);
423 } while (dev);
424
Simon Glass71fa5b42020-12-03 16:55:18 -0700425 /* Now the child plat should be removed and re-added */
Simon Glass11b61732015-01-25 08:27:01 -0700426 device_probe(bus);
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530427 for (device_find_first_child(bus, &dev);
Simon Glass11b61732015-01-25 08:27:01 -0700428 dev;
429 device_find_next_child(&dev)) {
430 /* Check that platform data is allocated */
Simon Glass71fa5b42020-12-03 16:55:18 -0700431 plat = dev_get_parent_plat(dev);
Simon Glass11b61732015-01-25 08:27:01 -0700432 ut_assert(plat != NULL);
433 ut_asserteq(0, plat->count);
Simon Glass11b61732015-01-25 08:27:01 -0700434 }
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530435 ut_asserteq(3, device_get_child_count(bus));
Simon Glass11b61732015-01-25 08:27:01 -0700436
437 return 0;
438}
Simon Glass57f95402015-01-25 08:27:02 -0700439
440/* Test that the bus can store platform data about each child */
Simon Glass71fa5b42020-12-03 16:55:18 -0700441static int dm_test_bus_parent_plat(struct unit_test_state *uts)
Simon Glass57f95402015-01-25 08:27:02 -0700442{
Simon Glass71fa5b42020-12-03 16:55:18 -0700443 return test_bus_parent_plat(uts);
Simon Glass57f95402015-01-25 08:27:02 -0700444}
Simon Glass71fa5b42020-12-03 16:55:18 -0700445DM_TEST(dm_test_bus_parent_plat, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass57f95402015-01-25 08:27:02 -0700446
447/* As above but the size is controlled by the uclass */
Simon Glass71fa5b42020-12-03 16:55:18 -0700448static int dm_test_bus_parent_plat_uclass(struct unit_test_state *uts)
Simon Glass57f95402015-01-25 08:27:02 -0700449{
450 struct udevice *bus;
Simon Glass2410d882015-03-25 12:21:51 -0600451 struct driver *drv;
Simon Glass57f95402015-01-25 08:27:02 -0700452 int size;
453 int ret;
454
455 /* Set the driver size to 0 so that the uclass size is used */
456 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
Simon Glass2410d882015-03-25 12:21:51 -0600457 drv = (struct driver *)bus->driver;
Simon Glass71fa5b42020-12-03 16:55:18 -0700458 size = drv->per_child_plat_auto;
Simon Glass4e766c22018-10-01 21:12:32 -0600459#ifdef CONFIG_SANDBOX
460 os_mprotect_allow(bus->uclass->uc_drv, sizeof(*bus->uclass->uc_drv));
461 os_mprotect_allow(drv, sizeof(*drv));
462#endif
Simon Glass71fa5b42020-12-03 16:55:18 -0700463 bus->uclass->uc_drv->per_child_plat_auto = size;
464 drv->per_child_plat_auto = 0;
465 ret = test_bus_parent_plat(uts);
Simon Glass57f95402015-01-25 08:27:02 -0700466 if (ret)
467 return ret;
Simon Glass71fa5b42020-12-03 16:55:18 -0700468 bus->uclass->uc_drv->per_child_plat_auto = 0;
469 drv->per_child_plat_auto = size;
Simon Glass57f95402015-01-25 08:27:02 -0700470
471 return 0;
472}
Simon Glass71fa5b42020-12-03 16:55:18 -0700473DM_TEST(dm_test_bus_parent_plat_uclass,
Simon Glass974dccd2020-07-28 19:41:12 -0600474 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glassa4a51a02015-01-25 08:27:03 -0700475
476/* Test that the child post_bind method is called */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500477static int dm_test_bus_child_post_bind(struct unit_test_state *uts)
Simon Glassa4a51a02015-01-25 08:27:03 -0700478{
Simon Glass71fa5b42020-12-03 16:55:18 -0700479 struct dm_test_parent_plat *plat;
Simon Glassa4a51a02015-01-25 08:27:03 -0700480 struct udevice *bus, *dev;
Simon Glassa4a51a02015-01-25 08:27:03 -0700481
482 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530483 for (device_find_first_child(bus, &dev);
Simon Glassa4a51a02015-01-25 08:27:03 -0700484 dev;
485 device_find_next_child(&dev)) {
486 /* Check that platform data is allocated */
Simon Glass71fa5b42020-12-03 16:55:18 -0700487 plat = dev_get_parent_plat(dev);
Simon Glassa4a51a02015-01-25 08:27:03 -0700488 ut_assert(plat != NULL);
489 ut_asserteq(1, plat->bind_flag);
Simon Glassa4a51a02015-01-25 08:27:03 -0700490 }
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530491 ut_asserteq(3, device_get_child_count(bus));
Simon Glassa4a51a02015-01-25 08:27:03 -0700492
493 return 0;
494}
Simon Glass974dccd2020-07-28 19:41:12 -0600495DM_TEST(dm_test_bus_child_post_bind, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glassf4c9b3e2015-01-25 08:27:08 -0700496
497/* Test that the child post_bind method is called */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500498static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts)
Simon Glassf4c9b3e2015-01-25 08:27:08 -0700499{
Simon Glass71fa5b42020-12-03 16:55:18 -0700500 struct dm_test_parent_plat *plat;
Simon Glassf4c9b3e2015-01-25 08:27:08 -0700501 struct udevice *bus, *dev;
Simon Glassf4c9b3e2015-01-25 08:27:08 -0700502
503 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530504 for (device_find_first_child(bus, &dev);
Simon Glassf4c9b3e2015-01-25 08:27:08 -0700505 dev;
506 device_find_next_child(&dev)) {
507 /* Check that platform data is allocated */
Simon Glass71fa5b42020-12-03 16:55:18 -0700508 plat = dev_get_parent_plat(dev);
Simon Glassf4c9b3e2015-01-25 08:27:08 -0700509 ut_assert(plat != NULL);
510 ut_asserteq(2, plat->uclass_bind_flag);
Simon Glassf4c9b3e2015-01-25 08:27:08 -0700511 }
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530512 ut_asserteq(3, device_get_child_count(bus));
Simon Glassf4c9b3e2015-01-25 08:27:08 -0700513
514 return 0;
515}
516DM_TEST(dm_test_bus_child_post_bind_uclass,
Simon Glass974dccd2020-07-28 19:41:12 -0600517 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass5104b982015-01-25 08:27:10 -0700518
519/*
520 * Test that the bus' uclass' child_pre_probe() is called before the
521 * device's probe() method
522 */
Joe Hershberger3a77be52015-05-20 14:27:27 -0500523static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
Simon Glass5104b982015-01-25 08:27:10 -0700524{
525 struct udevice *bus, *dev;
Simon Glass5104b982015-01-25 08:27:10 -0700526
527 /*
528 * See testfdt_drv_probe() which effectively checks that the uclass
529 * flag is set before that method is called
530 */
531 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530532 for (device_find_first_child(bus, &dev);
Simon Glass5104b982015-01-25 08:27:10 -0700533 dev;
534 device_find_next_child(&dev)) {
535 struct dm_test_priv *priv = dev_get_priv(dev);
536
537 /* Check that things happened in the right order */
538 ut_asserteq_ptr(NULL, priv);
539 ut_assertok(device_probe(dev));
540
541 priv = dev_get_priv(dev);
542 ut_assert(priv != NULL);
543 ut_asserteq(1, priv->uclass_flag);
544 ut_asserteq(1, priv->uclass_total);
Simon Glass5104b982015-01-25 08:27:10 -0700545 }
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530546 ut_asserteq(3, device_get_child_count(bus));
Simon Glass5104b982015-01-25 08:27:10 -0700547
548 return 0;
549}
550DM_TEST(dm_test_bus_child_pre_probe_uclass,
Simon Glass974dccd2020-07-28 19:41:12 -0600551 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Bin Mengd9bad172018-10-15 02:20:58 -0700552
553/*
554 * Test that the bus' uclass' child_post_probe() is called after the
555 * device's probe() method
556 */
557static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts)
558{
559 struct udevice *bus, *dev;
Bin Mengd9bad172018-10-15 02:20:58 -0700560
561 /*
562 * See testfdt_drv_probe() which effectively initializes that
563 * the uclass postp flag is set to a value
564 */
565 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530566 for (device_find_first_child(bus, &dev);
Bin Mengd9bad172018-10-15 02:20:58 -0700567 dev;
568 device_find_next_child(&dev)) {
569 struct dm_test_priv *priv = dev_get_priv(dev);
570
571 /* Check that things happened in the right order */
572 ut_asserteq_ptr(NULL, priv);
573 ut_assertok(device_probe(dev));
574
575 priv = dev_get_priv(dev);
576 ut_assert(priv != NULL);
577 ut_asserteq(0, priv->uclass_postp);
Bin Mengd9bad172018-10-15 02:20:58 -0700578 }
Lokesh Vutlafa45a082019-09-04 16:01:26 +0530579 ut_asserteq(3, device_get_child_count(bus));
Bin Mengd9bad172018-10-15 02:20:58 -0700580
581 return 0;
582}
583DM_TEST(dm_test_bus_child_post_probe_uclass,
Simon Glass974dccd2020-07-28 19:41:12 -0600584 UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);