blob: d0cd5a009cdebd5eda63d8c47705ca5b01154eb1 [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
8#include <os.h>
9#endif
Simon Glass1ca7e202014-07-23 06:55:18 -060010#include <dm.h>
Simon Glasse59f4582014-07-23 06:55:20 -060011#include <dm/device-internal.h>
Simon Glass1ca7e202014-07-23 06:55:18 -060012#include <dm/test.h>
Simon Glasscdc133b2015-01-25 08:27:01 -070013#include <dm/uclass-internal.h>
Simon Glass1ca7e202014-07-23 06:55:18 -060014#include <dm/util.h>
Joe Hershbergere721b882015-05-20 14:27:27 -050015#include <test/ut.h>
Simon Glass1ca7e202014-07-23 06:55:18 -060016
17DECLARE_GLOBAL_DATA_PTR;
18
Simon Glasscdc133b2015-01-25 08:27:01 -070019struct dm_test_parent_platdata {
20 int count;
Simon Glass0118ce72015-01-25 08:27:03 -070021 int bind_flag;
Simon Glass081f2fc2015-01-25 08:27:08 -070022 int uclass_bind_flag;
Simon Glasscdc133b2015-01-25 08:27:01 -070023};
24
Simon Glassa327dee2014-07-23 06:55:21 -060025enum {
26 FLAG_CHILD_PROBED = 10,
27 FLAG_CHILD_REMOVED = -7,
28};
29
30static struct dm_test_state *test_state;
31
Simon Glass1ca7e202014-07-23 06:55:18 -060032static int testbus_drv_probe(struct udevice *dev)
33{
Simon Glass2e3f1ff2016-07-05 17:10:09 -060034 return dm_scan_fdt_dev(dev);
Simon Glass1ca7e202014-07-23 06:55:18 -060035}
36
Simon Glass0118ce72015-01-25 08:27:03 -070037static int testbus_child_post_bind(struct udevice *dev)
38{
39 struct dm_test_parent_platdata *plat;
40
41 plat = dev_get_parent_platdata(dev);
42 plat->bind_flag = 1;
Simon Glass081f2fc2015-01-25 08:27:08 -070043 plat->uclass_bind_flag = 2;
Simon Glass0118ce72015-01-25 08:27:03 -070044
45 return 0;
46}
47
Simon Glassa327dee2014-07-23 06:55:21 -060048static int testbus_child_pre_probe(struct udevice *dev)
49{
Simon Glassbcbe3d12015-09-28 23:32:01 -060050 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
Simon Glassa327dee2014-07-23 06:55:21 -060051
52 parent_data->flag += FLAG_CHILD_PROBED;
53
54 return 0;
55}
56
Simon Glass83c7e432015-01-25 08:27:10 -070057static int testbus_child_pre_probe_uclass(struct udevice *dev)
58{
59 struct dm_test_priv *priv = dev_get_priv(dev);
60
61 priv->uclass_flag++;
62
63 return 0;
64}
65
Simon Glassa327dee2014-07-23 06:55:21 -060066static int testbus_child_post_remove(struct udevice *dev)
67{
Simon Glassbcbe3d12015-09-28 23:32:01 -060068 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
Simon Glassa327dee2014-07-23 06:55:21 -060069 struct dm_test_state *dms = test_state;
70
71 parent_data->flag += FLAG_CHILD_REMOVED;
72 if (dms)
73 dms->removed = dev;
74
75 return 0;
76}
77
Simon Glass1ca7e202014-07-23 06:55:18 -060078static const struct udevice_id testbus_ids[] = {
79 {
80 .compatible = "denx,u-boot-test-bus",
81 .data = DM_TEST_TYPE_FIRST },
82 { }
83};
84
85U_BOOT_DRIVER(testbus_drv) = {
86 .name = "testbus_drv",
87 .of_match = testbus_ids,
88 .id = UCLASS_TEST_BUS,
89 .probe = testbus_drv_probe,
Simon Glass0118ce72015-01-25 08:27:03 -070090 .child_post_bind = testbus_child_post_bind,
Simon Glass1ca7e202014-07-23 06:55:18 -060091 .priv_auto_alloc_size = sizeof(struct dm_test_priv),
92 .platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
Simon Glasse59f4582014-07-23 06:55:20 -060093 .per_child_auto_alloc_size = sizeof(struct dm_test_parent_data),
Simon Glasscdc133b2015-01-25 08:27:01 -070094 .per_child_platdata_auto_alloc_size =
95 sizeof(struct dm_test_parent_platdata),
Simon Glassa327dee2014-07-23 06:55:21 -060096 .child_pre_probe = testbus_child_pre_probe,
97 .child_post_remove = testbus_child_post_remove,
Simon Glass1ca7e202014-07-23 06:55:18 -060098};
99
100UCLASS_DRIVER(testbus) = {
101 .name = "testbus",
102 .id = UCLASS_TEST_BUS,
Simon Glass9cc36a22015-01-25 08:27:05 -0700103 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glass83c7e432015-01-25 08:27:10 -0700104 .child_pre_probe = testbus_child_pre_probe_uclass,
Simon Glass1ca7e202014-07-23 06:55:18 -0600105};
106
107/* Test that we can probe for children */
Joe Hershbergere721b882015-05-20 14:27:27 -0500108static int dm_test_bus_children(struct unit_test_state *uts)
Simon Glass1ca7e202014-07-23 06:55:18 -0600109{
Bin Meng2786cd72018-10-10 22:07:01 -0700110 int num_devices = 8;
Simon Glass1ca7e202014-07-23 06:55:18 -0600111 struct udevice *bus;
112 struct uclass *uc;
113
114 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
115 ut_asserteq(num_devices, list_count_items(&uc->dev_head));
116
117 /* Probe the bus, which should yield 3 more devices */
118 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
119 num_devices += 3;
120
121 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
122 ut_asserteq(num_devices, list_count_items(&uc->dev_head));
123
Joe Hershbergere721b882015-05-20 14:27:27 -0500124 ut_assert(!dm_check_devices(uts, num_devices));
Simon Glass1ca7e202014-07-23 06:55:18 -0600125
126 return 0;
127}
128DM_TEST(dm_test_bus_children, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass997c87b2014-07-23 06:55:19 -0600129
130/* Test our functions for accessing children */
Joe Hershbergere721b882015-05-20 14:27:27 -0500131static int dm_test_bus_children_funcs(struct unit_test_state *uts)
Simon Glass997c87b2014-07-23 06:55:19 -0600132{
133 const void *blob = gd->fdt_blob;
134 struct udevice *bus, *dev;
135 int node;
136
137 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
138
139 /* device_get_child() */
140 ut_assertok(device_get_child(bus, 0, &dev));
141 ut_asserteq(-ENODEV, device_get_child(bus, 4, &dev));
142 ut_assertok(device_get_child_by_seq(bus, 5, &dev));
143 ut_assert(dev->flags & DM_FLAG_ACTIVATED);
144 ut_asserteq_str("c-test@5", dev->name);
145
146 /* Device with sequence number 0 should be accessible */
147 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, true, &dev));
148 ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
149 ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
150 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 0, false, &dev));
151 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
152 ut_assert(dev->flags & DM_FLAG_ACTIVATED);
153
154 /* There is no device with sequence number 2 */
155 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, false, &dev));
156 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, true, &dev));
157 ut_asserteq(-ENODEV, device_get_child_by_seq(bus, 2, &dev));
158
159 /* Looking for something that is not a child */
160 node = fdt_path_offset(blob, "/junk");
161 ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
162 node = fdt_path_offset(blob, "/d-test");
163 ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
164
Simon Glass298afb52017-05-18 20:09:43 -0600165 return 0;
166}
167DM_TEST(dm_test_bus_children_funcs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
168
169static int dm_test_bus_children_of_offset(struct unit_test_state *uts)
170{
171 const void *blob = gd->fdt_blob;
172 struct udevice *bus, *dev;
173 int node;
174
175 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
Simon Glass4f414d32017-06-07 10:28:44 -0600176 ut_assertnonnull(bus);
Simon Glass298afb52017-05-18 20:09:43 -0600177
Simon Glass997c87b2014-07-23 06:55:19 -0600178 /* Find a valid child */
179 node = fdt_path_offset(blob, "/some-bus/c-test@1");
Simon Glass298afb52017-05-18 20:09:43 -0600180 ut_assert(node > 0);
Simon Glass997c87b2014-07-23 06:55:19 -0600181 ut_assertok(device_find_child_by_of_offset(bus, node, &dev));
Simon Glass4f414d32017-06-07 10:28:44 -0600182 ut_assertnonnull(dev);
Simon Glass997c87b2014-07-23 06:55:19 -0600183 ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
184 ut_assertok(device_get_child_by_of_offset(bus, node, &dev));
Simon Glass4f414d32017-06-07 10:28:44 -0600185 ut_assertnonnull(dev);
Simon Glass997c87b2014-07-23 06:55:19 -0600186 ut_assert(dev->flags & DM_FLAG_ACTIVATED);
187
188 return 0;
189}
Simon Glass298afb52017-05-18 20:09:43 -0600190DM_TEST(dm_test_bus_children_of_offset,
191 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
Simon Glasse59f4582014-07-23 06:55:20 -0600192
Simon Glassa8981d42014-10-13 23:41:49 -0600193/* Test that we can iterate through children */
Joe Hershbergere721b882015-05-20 14:27:27 -0500194static int dm_test_bus_children_iterators(struct unit_test_state *uts)
Simon Glassa8981d42014-10-13 23:41:49 -0600195{
196 struct udevice *bus, *dev, *child;
197
198 /* Walk through the children one by one */
199 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
200 ut_assertok(device_find_first_child(bus, &dev));
201 ut_asserteq_str("c-test@5", dev->name);
202 ut_assertok(device_find_next_child(&dev));
203 ut_asserteq_str("c-test@0", dev->name);
204 ut_assertok(device_find_next_child(&dev));
205 ut_asserteq_str("c-test@1", dev->name);
206 ut_assertok(device_find_next_child(&dev));
207 ut_asserteq_ptr(dev, NULL);
208
209 /* Move to the next child without using device_find_first_child() */
210 ut_assertok(device_find_child_by_seq(bus, 5, true, &dev));
211 ut_asserteq_str("c-test@5", dev->name);
212 ut_assertok(device_find_next_child(&dev));
213 ut_asserteq_str("c-test@0", dev->name);
214
215 /* Try a device with no children */
216 ut_assertok(device_find_first_child(dev, &child));
217 ut_asserteq_ptr(child, NULL);
218
219 return 0;
220}
221DM_TEST(dm_test_bus_children_iterators,
222 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
223
Simon Glasse59f4582014-07-23 06:55:20 -0600224/* Test that the bus can store data about each child */
Joe Hershbergere721b882015-05-20 14:27:27 -0500225static int test_bus_parent_data(struct unit_test_state *uts)
Simon Glasse59f4582014-07-23 06:55:20 -0600226{
227 struct dm_test_parent_data *parent_data;
228 struct udevice *bus, *dev;
229 struct uclass *uc;
230 int value;
231
232 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
233
234 /* Check that parent data is allocated */
235 ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600236 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glasse59f4582014-07-23 06:55:20 -0600237 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600238 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600239 ut_assert(NULL != parent_data);
240
241 /* Check that it starts at 0 and goes away when device is removed */
242 parent_data->sum += 5;
243 ut_asserteq(5, parent_data->sum);
Stefan Roese706865a2017-03-20 12:51:48 +0100244 device_remove(dev, DM_REMOVE_NORMAL);
Simon Glassbcbe3d12015-09-28 23:32:01 -0600245 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glasse59f4582014-07-23 06:55:20 -0600246
247 /* Check that we can do this twice */
248 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600249 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600250 ut_assert(NULL != parent_data);
251 parent_data->sum += 5;
252 ut_asserteq(5, parent_data->sum);
253
254 /* Add parent data to all children */
255 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
256 value = 5;
257 uclass_foreach_dev(dev, uc) {
258 /* Ignore these if they are not on this bus */
259 if (dev->parent != bus) {
Simon Glassbcbe3d12015-09-28 23:32:01 -0600260 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glasse59f4582014-07-23 06:55:20 -0600261 continue;
262 }
263 ut_assertok(device_probe(dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600264 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600265
266 parent_data->sum = value;
267 value += 5;
268 }
269
270 /* Check it is still there */
271 value = 5;
272 uclass_foreach_dev(dev, uc) {
273 /* Ignore these if they are not on this bus */
274 if (dev->parent != bus)
275 continue;
Simon Glassbcbe3d12015-09-28 23:32:01 -0600276 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600277
278 ut_asserteq(value, parent_data->sum);
279 value += 5;
280 }
281
282 return 0;
283}
Simon Glassdac8db22015-01-25 08:27:06 -0700284/* Test that the bus can store data about each child */
Joe Hershbergere721b882015-05-20 14:27:27 -0500285static int dm_test_bus_parent_data(struct unit_test_state *uts)
Simon Glassdac8db22015-01-25 08:27:06 -0700286{
Joe Hershbergere721b882015-05-20 14:27:27 -0500287 return test_bus_parent_data(uts);
Simon Glassdac8db22015-01-25 08:27:06 -0700288}
Simon Glasse59f4582014-07-23 06:55:20 -0600289DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glassa327dee2014-07-23 06:55:21 -0600290
Simon Glassdac8db22015-01-25 08:27:06 -0700291/* As above but the size is controlled by the uclass */
Joe Hershbergere721b882015-05-20 14:27:27 -0500292static int dm_test_bus_parent_data_uclass(struct unit_test_state *uts)
Simon Glassdac8db22015-01-25 08:27:06 -0700293{
Simon Glasse23eb612015-03-25 12:21:51 -0600294 struct driver *drv;
Simon Glassdac8db22015-01-25 08:27:06 -0700295 struct udevice *bus;
296 int size;
297 int ret;
298
299 /* Set the driver size to 0 so that the uclass size is used */
300 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
Simon Glasse23eb612015-03-25 12:21:51 -0600301 drv = (struct driver *)bus->driver;
302 size = drv->per_child_auto_alloc_size;
Simon Glass9f8037e2018-10-01 21:12:32 -0600303
304#ifdef CONFIG_SANDBOX
305 os_mprotect_allow(bus->uclass->uc_drv, sizeof(*bus->uclass->uc_drv));
306 os_mprotect_allow(drv, sizeof(*drv));
307#endif
Simon Glassdac8db22015-01-25 08:27:06 -0700308 bus->uclass->uc_drv->per_child_auto_alloc_size = size;
Simon Glasse23eb612015-03-25 12:21:51 -0600309 drv->per_child_auto_alloc_size = 0;
Joe Hershbergere721b882015-05-20 14:27:27 -0500310 ret = test_bus_parent_data(uts);
Simon Glassdac8db22015-01-25 08:27:06 -0700311 if (ret)
312 return ret;
313 bus->uclass->uc_drv->per_child_auto_alloc_size = 0;
Simon Glasse23eb612015-03-25 12:21:51 -0600314 drv->per_child_auto_alloc_size = size;
Simon Glassdac8db22015-01-25 08:27:06 -0700315
316 return 0;
317}
318DM_TEST(dm_test_bus_parent_data_uclass,
319 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
320
Simon Glassa327dee2014-07-23 06:55:21 -0600321/* Test that the bus ops are called when a child is probed/removed */
Joe Hershbergere721b882015-05-20 14:27:27 -0500322static int dm_test_bus_parent_ops(struct unit_test_state *uts)
Simon Glassa327dee2014-07-23 06:55:21 -0600323{
324 struct dm_test_parent_data *parent_data;
Joe Hershbergere721b882015-05-20 14:27:27 -0500325 struct dm_test_state *dms = uts->priv;
Simon Glassa327dee2014-07-23 06:55:21 -0600326 struct udevice *bus, *dev;
327 struct uclass *uc;
328
329 test_state = dms;
330 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
331 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
332
333 uclass_foreach_dev(dev, uc) {
334 /* Ignore these if they are not on this bus */
335 if (dev->parent != bus)
336 continue;
Simon Glassbcbe3d12015-09-28 23:32:01 -0600337 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glassa327dee2014-07-23 06:55:21 -0600338
339 ut_assertok(device_probe(dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600340 parent_data = dev_get_parent_priv(dev);
Simon Glassa327dee2014-07-23 06:55:21 -0600341 ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
342 }
343
344 uclass_foreach_dev(dev, uc) {
345 /* Ignore these if they are not on this bus */
346 if (dev->parent != bus)
347 continue;
Simon Glassbcbe3d12015-09-28 23:32:01 -0600348 parent_data = dev_get_parent_priv(dev);
Simon Glassa327dee2014-07-23 06:55:21 -0600349 ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
Stefan Roese706865a2017-03-20 12:51:48 +0100350 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600351 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glassa327dee2014-07-23 06:55:21 -0600352 ut_asserteq_ptr(dms->removed, dev);
353 }
354 test_state = NULL;
355
356 return 0;
357}
358DM_TEST(dm_test_bus_parent_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glasscdc133b2015-01-25 08:27:01 -0700359
Joe Hershbergere721b882015-05-20 14:27:27 -0500360static int test_bus_parent_platdata(struct unit_test_state *uts)
Simon Glasscdc133b2015-01-25 08:27:01 -0700361{
362 struct dm_test_parent_platdata *plat;
363 struct udevice *bus, *dev;
364 int child_count;
365
366 /* Check that the bus has no children */
367 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
368 device_find_first_child(bus, &dev);
369 ut_asserteq_ptr(NULL, dev);
370
371 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
372
373 for (device_find_first_child(bus, &dev), child_count = 0;
374 dev;
375 device_find_next_child(&dev)) {
376 /* Check that platform data is allocated */
377 plat = dev_get_parent_platdata(dev);
378 ut_assert(plat != NULL);
379
380 /*
381 * Check that it is not affected by the device being
382 * probed/removed
383 */
384 plat->count++;
385 ut_asserteq(1, plat->count);
386 device_probe(dev);
Stefan Roese706865a2017-03-20 12:51:48 +0100387 device_remove(dev, DM_REMOVE_NORMAL);
Simon Glasscdc133b2015-01-25 08:27:01 -0700388
389 ut_asserteq_ptr(plat, dev_get_parent_platdata(dev));
390 ut_asserteq(1, plat->count);
391 ut_assertok(device_probe(dev));
392 child_count++;
393 }
394 ut_asserteq(3, child_count);
395
396 /* Removing the bus should also have no effect (it is still bound) */
Stefan Roese706865a2017-03-20 12:51:48 +0100397 device_remove(bus, DM_REMOVE_NORMAL);
Simon Glasscdc133b2015-01-25 08:27:01 -0700398 for (device_find_first_child(bus, &dev), child_count = 0;
399 dev;
400 device_find_next_child(&dev)) {
401 /* Check that platform data is allocated */
402 plat = dev_get_parent_platdata(dev);
403 ut_assert(plat != NULL);
404 ut_asserteq(1, plat->count);
405 child_count++;
406 }
407 ut_asserteq(3, child_count);
408
409 /* Unbind all the children */
410 do {
411 device_find_first_child(bus, &dev);
412 if (dev)
413 device_unbind(dev);
414 } while (dev);
415
416 /* Now the child platdata should be removed and re-added */
417 device_probe(bus);
418 for (device_find_first_child(bus, &dev), child_count = 0;
419 dev;
420 device_find_next_child(&dev)) {
421 /* Check that platform data is allocated */
422 plat = dev_get_parent_platdata(dev);
423 ut_assert(plat != NULL);
424 ut_asserteq(0, plat->count);
425 child_count++;
426 }
427 ut_asserteq(3, child_count);
428
429 return 0;
430}
Simon Glassba8da9d2015-01-25 08:27:02 -0700431
432/* Test that the bus can store platform data about each child */
Joe Hershbergere721b882015-05-20 14:27:27 -0500433static int dm_test_bus_parent_platdata(struct unit_test_state *uts)
Simon Glassba8da9d2015-01-25 08:27:02 -0700434{
Joe Hershbergere721b882015-05-20 14:27:27 -0500435 return test_bus_parent_platdata(uts);
Simon Glassba8da9d2015-01-25 08:27:02 -0700436}
Simon Glasscdc133b2015-01-25 08:27:01 -0700437DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glassba8da9d2015-01-25 08:27:02 -0700438
439/* As above but the size is controlled by the uclass */
Joe Hershbergere721b882015-05-20 14:27:27 -0500440static int dm_test_bus_parent_platdata_uclass(struct unit_test_state *uts)
Simon Glassba8da9d2015-01-25 08:27:02 -0700441{
442 struct udevice *bus;
Simon Glasse23eb612015-03-25 12:21:51 -0600443 struct driver *drv;
Simon Glassba8da9d2015-01-25 08:27:02 -0700444 int size;
445 int ret;
446
447 /* Set the driver size to 0 so that the uclass size is used */
448 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
Simon Glasse23eb612015-03-25 12:21:51 -0600449 drv = (struct driver *)bus->driver;
450 size = drv->per_child_platdata_auto_alloc_size;
Simon Glass9f8037e2018-10-01 21:12:32 -0600451#ifdef CONFIG_SANDBOX
452 os_mprotect_allow(bus->uclass->uc_drv, sizeof(*bus->uclass->uc_drv));
453 os_mprotect_allow(drv, sizeof(*drv));
454#endif
Simon Glassba8da9d2015-01-25 08:27:02 -0700455 bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size;
Simon Glasse23eb612015-03-25 12:21:51 -0600456 drv->per_child_platdata_auto_alloc_size = 0;
Joe Hershbergere721b882015-05-20 14:27:27 -0500457 ret = test_bus_parent_platdata(uts);
Simon Glassba8da9d2015-01-25 08:27:02 -0700458 if (ret)
459 return ret;
460 bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0;
Simon Glasse23eb612015-03-25 12:21:51 -0600461 drv->per_child_platdata_auto_alloc_size = size;
Simon Glassba8da9d2015-01-25 08:27:02 -0700462
463 return 0;
464}
465DM_TEST(dm_test_bus_parent_platdata_uclass,
466 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass0118ce72015-01-25 08:27:03 -0700467
468/* Test that the child post_bind method is called */
Joe Hershbergere721b882015-05-20 14:27:27 -0500469static int dm_test_bus_child_post_bind(struct unit_test_state *uts)
Simon Glass0118ce72015-01-25 08:27:03 -0700470{
471 struct dm_test_parent_platdata *plat;
472 struct udevice *bus, *dev;
473 int child_count;
474
475 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
476 for (device_find_first_child(bus, &dev), child_count = 0;
477 dev;
478 device_find_next_child(&dev)) {
479 /* Check that platform data is allocated */
480 plat = dev_get_parent_platdata(dev);
481 ut_assert(plat != NULL);
482 ut_asserteq(1, plat->bind_flag);
483 child_count++;
484 }
485 ut_asserteq(3, child_count);
486
487 return 0;
488}
489DM_TEST(dm_test_bus_child_post_bind, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass081f2fc2015-01-25 08:27:08 -0700490
491/* Test that the child post_bind method is called */
Joe Hershbergere721b882015-05-20 14:27:27 -0500492static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts)
Simon Glass081f2fc2015-01-25 08:27:08 -0700493{
494 struct dm_test_parent_platdata *plat;
495 struct udevice *bus, *dev;
496 int child_count;
497
498 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
499 for (device_find_first_child(bus, &dev), child_count = 0;
500 dev;
501 device_find_next_child(&dev)) {
502 /* Check that platform data is allocated */
503 plat = dev_get_parent_platdata(dev);
504 ut_assert(plat != NULL);
505 ut_asserteq(2, plat->uclass_bind_flag);
506 child_count++;
507 }
508 ut_asserteq(3, child_count);
509
510 return 0;
511}
512DM_TEST(dm_test_bus_child_post_bind_uclass,
513 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass83c7e432015-01-25 08:27:10 -0700514
515/*
516 * Test that the bus' uclass' child_pre_probe() is called before the
517 * device's probe() method
518 */
Joe Hershbergere721b882015-05-20 14:27:27 -0500519static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
Simon Glass83c7e432015-01-25 08:27:10 -0700520{
521 struct udevice *bus, *dev;
522 int child_count;
523
524 /*
525 * See testfdt_drv_probe() which effectively checks that the uclass
526 * flag is set before that method is called
527 */
528 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
529 for (device_find_first_child(bus, &dev), child_count = 0;
530 dev;
531 device_find_next_child(&dev)) {
532 struct dm_test_priv *priv = dev_get_priv(dev);
533
534 /* Check that things happened in the right order */
535 ut_asserteq_ptr(NULL, priv);
536 ut_assertok(device_probe(dev));
537
538 priv = dev_get_priv(dev);
539 ut_assert(priv != NULL);
540 ut_asserteq(1, priv->uclass_flag);
541 ut_asserteq(1, priv->uclass_total);
542 child_count++;
543 }
544 ut_asserteq(3, child_count);
545
546 return 0;
547}
548DM_TEST(dm_test_bus_child_pre_probe_uclass,
549 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);