blob: 73eb3aede3d6752e8da19697c4df6fef6d0f1b35 [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>
Joe Hershbergere721b882015-05-20 14:27:27 -050017#include <test/ut.h>
Simon Glass1ca7e202014-07-23 06:55:18 -060018
19DECLARE_GLOBAL_DATA_PTR;
20
Simon Glasscdc133b2015-01-25 08:27:01 -070021struct dm_test_parent_platdata {
22 int count;
Simon Glass0118ce72015-01-25 08:27:03 -070023 int bind_flag;
Simon Glass081f2fc2015-01-25 08:27:08 -070024 int uclass_bind_flag;
Simon Glasscdc133b2015-01-25 08:27:01 -070025};
26
Simon Glassa327dee2014-07-23 06:55:21 -060027enum {
28 FLAG_CHILD_PROBED = 10,
29 FLAG_CHILD_REMOVED = -7,
30};
31
32static struct dm_test_state *test_state;
33
Simon Glass1ca7e202014-07-23 06:55:18 -060034static int testbus_drv_probe(struct udevice *dev)
35{
Simon Glass2e3f1ff2016-07-05 17:10:09 -060036 return dm_scan_fdt_dev(dev);
Simon Glass1ca7e202014-07-23 06:55:18 -060037}
38
Simon Glass0118ce72015-01-25 08:27:03 -070039static int testbus_child_post_bind(struct udevice *dev)
40{
41 struct dm_test_parent_platdata *plat;
42
43 plat = dev_get_parent_platdata(dev);
44 plat->bind_flag = 1;
Simon Glass081f2fc2015-01-25 08:27:08 -070045 plat->uclass_bind_flag = 2;
Simon Glass0118ce72015-01-25 08:27:03 -070046
47 return 0;
48}
49
Simon Glassa327dee2014-07-23 06:55:21 -060050static int testbus_child_pre_probe(struct udevice *dev)
51{
Simon Glassbcbe3d12015-09-28 23:32:01 -060052 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
Simon Glassa327dee2014-07-23 06:55:21 -060053
54 parent_data->flag += FLAG_CHILD_PROBED;
55
56 return 0;
57}
58
Simon Glass83c7e432015-01-25 08:27:10 -070059static int testbus_child_pre_probe_uclass(struct udevice *dev)
60{
61 struct dm_test_priv *priv = dev_get_priv(dev);
62
63 priv->uclass_flag++;
64
65 return 0;
66}
67
Bin Mengd92878a2018-10-15 02:20:58 -070068static int testbus_child_post_probe_uclass(struct udevice *dev)
69{
70 struct dm_test_priv *priv = dev_get_priv(dev);
71
72 priv->uclass_postp++;
73
74 return 0;
75}
76
Simon Glassa327dee2014-07-23 06:55:21 -060077static int testbus_child_post_remove(struct udevice *dev)
78{
Simon Glassbcbe3d12015-09-28 23:32:01 -060079 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
Simon Glassa327dee2014-07-23 06:55:21 -060080 struct dm_test_state *dms = test_state;
81
82 parent_data->flag += FLAG_CHILD_REMOVED;
83 if (dms)
84 dms->removed = dev;
85
86 return 0;
87}
88
Simon Glass1ca7e202014-07-23 06:55:18 -060089static const struct udevice_id testbus_ids[] = {
90 {
91 .compatible = "denx,u-boot-test-bus",
92 .data = DM_TEST_TYPE_FIRST },
93 { }
94};
95
96U_BOOT_DRIVER(testbus_drv) = {
97 .name = "testbus_drv",
98 .of_match = testbus_ids,
99 .id = UCLASS_TEST_BUS,
100 .probe = testbus_drv_probe,
Simon Glass0118ce72015-01-25 08:27:03 -0700101 .child_post_bind = testbus_child_post_bind,
Simon Glass1ca7e202014-07-23 06:55:18 -0600102 .priv_auto_alloc_size = sizeof(struct dm_test_priv),
103 .platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
Simon Glasse59f4582014-07-23 06:55:20 -0600104 .per_child_auto_alloc_size = sizeof(struct dm_test_parent_data),
Simon Glasscdc133b2015-01-25 08:27:01 -0700105 .per_child_platdata_auto_alloc_size =
106 sizeof(struct dm_test_parent_platdata),
Simon Glassa327dee2014-07-23 06:55:21 -0600107 .child_pre_probe = testbus_child_pre_probe,
108 .child_post_remove = testbus_child_post_remove,
Simon Glass1ca7e202014-07-23 06:55:18 -0600109};
110
111UCLASS_DRIVER(testbus) = {
112 .name = "testbus",
113 .id = UCLASS_TEST_BUS,
Simon Glass9cc36a22015-01-25 08:27:05 -0700114 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glass83c7e432015-01-25 08:27:10 -0700115 .child_pre_probe = testbus_child_pre_probe_uclass,
Bin Mengd92878a2018-10-15 02:20:58 -0700116 .child_post_probe = testbus_child_post_probe_uclass,
Simon Glass1ca7e202014-07-23 06:55:18 -0600117};
118
119/* Test that we can probe for children */
Joe Hershbergere721b882015-05-20 14:27:27 -0500120static int dm_test_bus_children(struct unit_test_state *uts)
Simon Glass1ca7e202014-07-23 06:55:18 -0600121{
Bin Meng2786cd72018-10-10 22:07:01 -0700122 int num_devices = 8;
Simon Glass1ca7e202014-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 Hershbergere721b882015-05-20 14:27:27 -0500136 ut_assert(!dm_check_devices(uts, num_devices));
Simon Glass1ca7e202014-07-23 06:55:18 -0600137
138 return 0;
139}
140DM_TEST(dm_test_bus_children, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass997c87b2014-07-23 06:55:19 -0600141
142/* Test our functions for accessing children */
Joe Hershbergere721b882015-05-20 14:27:27 -0500143static int dm_test_bus_children_funcs(struct unit_test_state *uts)
Simon Glass997c87b2014-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 Glass298afb52017-05-18 20:09:43 -0600177 return 0;
178}
179DM_TEST(dm_test_bus_children_funcs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
180
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 Glass4f414d32017-06-07 10:28:44 -0600188 ut_assertnonnull(bus);
Simon Glass298afb52017-05-18 20:09:43 -0600189
Simon Glass997c87b2014-07-23 06:55:19 -0600190 /* Find a valid child */
191 node = fdt_path_offset(blob, "/some-bus/c-test@1");
Simon Glass298afb52017-05-18 20:09:43 -0600192 ut_assert(node > 0);
Simon Glass997c87b2014-07-23 06:55:19 -0600193 ut_assertok(device_find_child_by_of_offset(bus, node, &dev));
Simon Glass4f414d32017-06-07 10:28:44 -0600194 ut_assertnonnull(dev);
Simon Glass997c87b2014-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 Glass4f414d32017-06-07 10:28:44 -0600197 ut_assertnonnull(dev);
Simon Glass997c87b2014-07-23 06:55:19 -0600198 ut_assert(dev->flags & DM_FLAG_ACTIVATED);
199
200 return 0;
201}
Simon Glass298afb52017-05-18 20:09:43 -0600202DM_TEST(dm_test_bus_children_of_offset,
203 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
Simon Glasse59f4582014-07-23 06:55:20 -0600204
Simon Glassa8981d42014-10-13 23:41:49 -0600205/* Test that we can iterate through children */
Joe Hershbergere721b882015-05-20 14:27:27 -0500206static int dm_test_bus_children_iterators(struct unit_test_state *uts)
Simon Glassa8981d42014-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,
234 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
235
Simon Glasse59f4582014-07-23 06:55:20 -0600236/* Test that the bus can store data about each child */
Joe Hershbergere721b882015-05-20 14:27:27 -0500237static int test_bus_parent_data(struct unit_test_state *uts)
Simon Glasse59f4582014-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 Glassbcbe3d12015-09-28 23:32:01 -0600248 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glasse59f4582014-07-23 06:55:20 -0600249 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600250 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-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 Roese706865a2017-03-20 12:51:48 +0100256 device_remove(dev, DM_REMOVE_NORMAL);
Simon Glassbcbe3d12015-09-28 23:32:01 -0600257 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glasse59f4582014-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 Glassbcbe3d12015-09-28 23:32:01 -0600261 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-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 Glassbcbe3d12015-09-28 23:32:01 -0600272 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glasse59f4582014-07-23 06:55:20 -0600273 continue;
274 }
275 ut_assertok(device_probe(dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600276 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-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 Glassbcbe3d12015-09-28 23:32:01 -0600288 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600289
290 ut_asserteq(value, parent_data->sum);
291 value += 5;
292 }
293
294 return 0;
295}
Simon Glassdac8db22015-01-25 08:27:06 -0700296/* Test that the bus can store data about each child */
Joe Hershbergere721b882015-05-20 14:27:27 -0500297static int dm_test_bus_parent_data(struct unit_test_state *uts)
Simon Glassdac8db22015-01-25 08:27:06 -0700298{
Joe Hershbergere721b882015-05-20 14:27:27 -0500299 return test_bus_parent_data(uts);
Simon Glassdac8db22015-01-25 08:27:06 -0700300}
Simon Glasse59f4582014-07-23 06:55:20 -0600301DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glassa327dee2014-07-23 06:55:21 -0600302
Simon Glassdac8db22015-01-25 08:27:06 -0700303/* As above but the size is controlled by the uclass */
Joe Hershbergere721b882015-05-20 14:27:27 -0500304static int dm_test_bus_parent_data_uclass(struct unit_test_state *uts)
Simon Glassdac8db22015-01-25 08:27:06 -0700305{
Simon Glasse23eb612015-03-25 12:21:51 -0600306 struct driver *drv;
Simon Glassdac8db22015-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 Glasse23eb612015-03-25 12:21:51 -0600313 drv = (struct driver *)bus->driver;
314 size = drv->per_child_auto_alloc_size;
Simon Glass9f8037e2018-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 Glassdac8db22015-01-25 08:27:06 -0700320 bus->uclass->uc_drv->per_child_auto_alloc_size = size;
Simon Glasse23eb612015-03-25 12:21:51 -0600321 drv->per_child_auto_alloc_size = 0;
Joe Hershbergere721b882015-05-20 14:27:27 -0500322 ret = test_bus_parent_data(uts);
Simon Glassdac8db22015-01-25 08:27:06 -0700323 if (ret)
324 return ret;
325 bus->uclass->uc_drv->per_child_auto_alloc_size = 0;
Simon Glasse23eb612015-03-25 12:21:51 -0600326 drv->per_child_auto_alloc_size = size;
Simon Glassdac8db22015-01-25 08:27:06 -0700327
328 return 0;
329}
330DM_TEST(dm_test_bus_parent_data_uclass,
331 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
332
Simon Glassa327dee2014-07-23 06:55:21 -0600333/* Test that the bus ops are called when a child is probed/removed */
Joe Hershbergere721b882015-05-20 14:27:27 -0500334static int dm_test_bus_parent_ops(struct unit_test_state *uts)
Simon Glassa327dee2014-07-23 06:55:21 -0600335{
336 struct dm_test_parent_data *parent_data;
Joe Hershbergere721b882015-05-20 14:27:27 -0500337 struct dm_test_state *dms = uts->priv;
Simon Glassa327dee2014-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 Glassbcbe3d12015-09-28 23:32:01 -0600349 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glassa327dee2014-07-23 06:55:21 -0600350
351 ut_assertok(device_probe(dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600352 parent_data = dev_get_parent_priv(dev);
Simon Glassa327dee2014-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 Glassbcbe3d12015-09-28 23:32:01 -0600360 parent_data = dev_get_parent_priv(dev);
Simon Glassa327dee2014-07-23 06:55:21 -0600361 ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
Stefan Roese706865a2017-03-20 12:51:48 +0100362 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600363 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glassa327dee2014-07-23 06:55:21 -0600364 ut_asserteq_ptr(dms->removed, dev);
365 }
366 test_state = NULL;
367
368 return 0;
369}
370DM_TEST(dm_test_bus_parent_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glasscdc133b2015-01-25 08:27:01 -0700371
Joe Hershbergere721b882015-05-20 14:27:27 -0500372static int test_bus_parent_platdata(struct unit_test_state *uts)
Simon Glasscdc133b2015-01-25 08:27:01 -0700373{
374 struct dm_test_parent_platdata *plat;
375 struct udevice *bus, *dev;
Simon Glasscdc133b2015-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 Vutla240b9322019-09-04 16:01:26 +0530384 for (device_find_first_child(bus, &dev);
Simon Glasscdc133b2015-01-25 08:27:01 -0700385 dev;
386 device_find_next_child(&dev)) {
387 /* Check that platform data is allocated */
388 plat = dev_get_parent_platdata(dev);
389 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 Roese706865a2017-03-20 12:51:48 +0100398 device_remove(dev, DM_REMOVE_NORMAL);
Simon Glasscdc133b2015-01-25 08:27:01 -0700399
400 ut_asserteq_ptr(plat, dev_get_parent_platdata(dev));
401 ut_asserteq(1, plat->count);
402 ut_assertok(device_probe(dev));
Simon Glasscdc133b2015-01-25 08:27:01 -0700403 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530404 ut_asserteq(3, device_get_child_count(bus));
Simon Glasscdc133b2015-01-25 08:27:01 -0700405
406 /* Removing the bus should also have no effect (it is still bound) */
Stefan Roese706865a2017-03-20 12:51:48 +0100407 device_remove(bus, DM_REMOVE_NORMAL);
Lokesh Vutla240b9322019-09-04 16:01:26 +0530408 for (device_find_first_child(bus, &dev);
Simon Glasscdc133b2015-01-25 08:27:01 -0700409 dev;
410 device_find_next_child(&dev)) {
411 /* Check that platform data is allocated */
412 plat = dev_get_parent_platdata(dev);
413 ut_assert(plat != NULL);
414 ut_asserteq(1, plat->count);
Simon Glasscdc133b2015-01-25 08:27:01 -0700415 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530416 ut_asserteq(3, device_get_child_count(bus));
Simon Glasscdc133b2015-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
425 /* Now the child platdata should be removed and re-added */
426 device_probe(bus);
Lokesh Vutla240b9322019-09-04 16:01:26 +0530427 for (device_find_first_child(bus, &dev);
Simon Glasscdc133b2015-01-25 08:27:01 -0700428 dev;
429 device_find_next_child(&dev)) {
430 /* Check that platform data is allocated */
431 plat = dev_get_parent_platdata(dev);
432 ut_assert(plat != NULL);
433 ut_asserteq(0, plat->count);
Simon Glasscdc133b2015-01-25 08:27:01 -0700434 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530435 ut_asserteq(3, device_get_child_count(bus));
Simon Glasscdc133b2015-01-25 08:27:01 -0700436
437 return 0;
438}
Simon Glassba8da9d2015-01-25 08:27:02 -0700439
440/* Test that the bus can store platform data about each child */
Joe Hershbergere721b882015-05-20 14:27:27 -0500441static int dm_test_bus_parent_platdata(struct unit_test_state *uts)
Simon Glassba8da9d2015-01-25 08:27:02 -0700442{
Joe Hershbergere721b882015-05-20 14:27:27 -0500443 return test_bus_parent_platdata(uts);
Simon Glassba8da9d2015-01-25 08:27:02 -0700444}
Simon Glasscdc133b2015-01-25 08:27:01 -0700445DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glassba8da9d2015-01-25 08:27:02 -0700446
447/* As above but the size is controlled by the uclass */
Joe Hershbergere721b882015-05-20 14:27:27 -0500448static int dm_test_bus_parent_platdata_uclass(struct unit_test_state *uts)
Simon Glassba8da9d2015-01-25 08:27:02 -0700449{
450 struct udevice *bus;
Simon Glasse23eb612015-03-25 12:21:51 -0600451 struct driver *drv;
Simon Glassba8da9d2015-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 Glasse23eb612015-03-25 12:21:51 -0600457 drv = (struct driver *)bus->driver;
458 size = drv->per_child_platdata_auto_alloc_size;
Simon Glass9f8037e2018-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 Glassba8da9d2015-01-25 08:27:02 -0700463 bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size;
Simon Glasse23eb612015-03-25 12:21:51 -0600464 drv->per_child_platdata_auto_alloc_size = 0;
Joe Hershbergere721b882015-05-20 14:27:27 -0500465 ret = test_bus_parent_platdata(uts);
Simon Glassba8da9d2015-01-25 08:27:02 -0700466 if (ret)
467 return ret;
468 bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0;
Simon Glasse23eb612015-03-25 12:21:51 -0600469 drv->per_child_platdata_auto_alloc_size = size;
Simon Glassba8da9d2015-01-25 08:27:02 -0700470
471 return 0;
472}
473DM_TEST(dm_test_bus_parent_platdata_uclass,
474 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass0118ce72015-01-25 08:27:03 -0700475
476/* Test that the child post_bind method is called */
Joe Hershbergere721b882015-05-20 14:27:27 -0500477static int dm_test_bus_child_post_bind(struct unit_test_state *uts)
Simon Glass0118ce72015-01-25 08:27:03 -0700478{
479 struct dm_test_parent_platdata *plat;
480 struct udevice *bus, *dev;
Simon Glass0118ce72015-01-25 08:27:03 -0700481
482 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
Lokesh Vutla240b9322019-09-04 16:01:26 +0530483 for (device_find_first_child(bus, &dev);
Simon Glass0118ce72015-01-25 08:27:03 -0700484 dev;
485 device_find_next_child(&dev)) {
486 /* Check that platform data is allocated */
487 plat = dev_get_parent_platdata(dev);
488 ut_assert(plat != NULL);
489 ut_asserteq(1, plat->bind_flag);
Simon Glass0118ce72015-01-25 08:27:03 -0700490 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530491 ut_asserteq(3, device_get_child_count(bus));
Simon Glass0118ce72015-01-25 08:27:03 -0700492
493 return 0;
494}
495DM_TEST(dm_test_bus_child_post_bind, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass081f2fc2015-01-25 08:27:08 -0700496
497/* Test that the child post_bind method is called */
Joe Hershbergere721b882015-05-20 14:27:27 -0500498static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts)
Simon Glass081f2fc2015-01-25 08:27:08 -0700499{
500 struct dm_test_parent_platdata *plat;
501 struct udevice *bus, *dev;
Simon Glass081f2fc2015-01-25 08:27:08 -0700502
503 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
Lokesh Vutla240b9322019-09-04 16:01:26 +0530504 for (device_find_first_child(bus, &dev);
Simon Glass081f2fc2015-01-25 08:27:08 -0700505 dev;
506 device_find_next_child(&dev)) {
507 /* Check that platform data is allocated */
508 plat = dev_get_parent_platdata(dev);
509 ut_assert(plat != NULL);
510 ut_asserteq(2, plat->uclass_bind_flag);
Simon Glass081f2fc2015-01-25 08:27:08 -0700511 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530512 ut_asserteq(3, device_get_child_count(bus));
Simon Glass081f2fc2015-01-25 08:27:08 -0700513
514 return 0;
515}
516DM_TEST(dm_test_bus_child_post_bind_uclass,
517 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass83c7e432015-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 Hershbergere721b882015-05-20 14:27:27 -0500523static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
Simon Glass83c7e432015-01-25 08:27:10 -0700524{
525 struct udevice *bus, *dev;
Simon Glass83c7e432015-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 Vutla240b9322019-09-04 16:01:26 +0530532 for (device_find_first_child(bus, &dev);
Simon Glass83c7e432015-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 Glass83c7e432015-01-25 08:27:10 -0700545 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530546 ut_asserteq(3, device_get_child_count(bus));
Simon Glass83c7e432015-01-25 08:27:10 -0700547
548 return 0;
549}
550DM_TEST(dm_test_bus_child_pre_probe_uclass,
551 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Bin Mengd92878a2018-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 Mengd92878a2018-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 Vutla240b9322019-09-04 16:01:26 +0530566 for (device_find_first_child(bus, &dev);
Bin Mengd92878a2018-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 Mengd92878a2018-10-15 02:20:58 -0700578 }
Lokesh Vutla240b9322019-09-04 16:01:26 +0530579 ut_asserteq(3, device_get_child_count(bus));
Bin Mengd92878a2018-10-15 02:20:58 -0700580
581 return 0;
582}
583DM_TEST(dm_test_bus_child_post_probe_uclass,
584 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);