xref: /rk3399_rockchip-uboot/test/dm/bus.c (revision dac8db2ce66944828e441cccf25703b262a256cd)
11ca7e206SSimon Glass /*
21ca7e206SSimon Glass  * Copyright (c) 2014 Google, Inc
31ca7e206SSimon Glass  *
41ca7e206SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
51ca7e206SSimon Glass  */
61ca7e206SSimon Glass 
71ca7e206SSimon Glass #include <common.h>
81ca7e206SSimon Glass #include <dm.h>
9e59f458dSSimon Glass #include <dm/device-internal.h>
101ca7e206SSimon Glass #include <dm/root.h>
111ca7e206SSimon Glass #include <dm/test.h>
12cdc133bdSSimon Glass #include <dm/uclass-internal.h>
131ca7e206SSimon Glass #include <dm/ut.h>
141ca7e206SSimon Glass #include <dm/util.h>
151ca7e206SSimon Glass 
161ca7e206SSimon Glass DECLARE_GLOBAL_DATA_PTR;
171ca7e206SSimon Glass 
18cdc133bdSSimon Glass struct dm_test_parent_platdata {
19cdc133bdSSimon Glass 	int count;
200118ce79SSimon Glass 	int bind_flag;
21cdc133bdSSimon Glass };
22cdc133bdSSimon Glass 
23a327dee0SSimon Glass enum {
24a327dee0SSimon Glass 	FLAG_CHILD_PROBED	= 10,
25a327dee0SSimon Glass 	FLAG_CHILD_REMOVED	= -7,
26a327dee0SSimon Glass };
27a327dee0SSimon Glass 
28a327dee0SSimon Glass static struct dm_test_state *test_state;
29a327dee0SSimon Glass 
301ca7e206SSimon Glass static int testbus_drv_probe(struct udevice *dev)
311ca7e206SSimon Glass {
321ca7e206SSimon Glass 	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
331ca7e206SSimon Glass }
341ca7e206SSimon Glass 
350118ce79SSimon Glass static int testbus_child_post_bind(struct udevice *dev)
360118ce79SSimon Glass {
370118ce79SSimon Glass 	struct dm_test_parent_platdata *plat;
380118ce79SSimon Glass 
390118ce79SSimon Glass 	plat = dev_get_parent_platdata(dev);
400118ce79SSimon Glass 	plat->bind_flag = 1;
410118ce79SSimon Glass 
420118ce79SSimon Glass 	return 0;
430118ce79SSimon Glass }
440118ce79SSimon Glass 
45a327dee0SSimon Glass static int testbus_child_pre_probe(struct udevice *dev)
46a327dee0SSimon Glass {
47a327dee0SSimon Glass 	struct dm_test_parent_data *parent_data = dev_get_parentdata(dev);
48a327dee0SSimon Glass 
49a327dee0SSimon Glass 	parent_data->flag += FLAG_CHILD_PROBED;
50a327dee0SSimon Glass 
51a327dee0SSimon Glass 	return 0;
52a327dee0SSimon Glass }
53a327dee0SSimon Glass 
54a327dee0SSimon Glass static int testbus_child_post_remove(struct udevice *dev)
55a327dee0SSimon Glass {
56a327dee0SSimon Glass 	struct dm_test_parent_data *parent_data = dev_get_parentdata(dev);
57a327dee0SSimon Glass 	struct dm_test_state *dms = test_state;
58a327dee0SSimon Glass 
59a327dee0SSimon Glass 	parent_data->flag += FLAG_CHILD_REMOVED;
60a327dee0SSimon Glass 	if (dms)
61a327dee0SSimon Glass 		dms->removed = dev;
62a327dee0SSimon Glass 
63a327dee0SSimon Glass 	return 0;
64a327dee0SSimon Glass }
65a327dee0SSimon Glass 
661ca7e206SSimon Glass static const struct udevice_id testbus_ids[] = {
671ca7e206SSimon Glass 	{
681ca7e206SSimon Glass 		.compatible = "denx,u-boot-test-bus",
691ca7e206SSimon Glass 		.data = DM_TEST_TYPE_FIRST },
701ca7e206SSimon Glass 	{ }
711ca7e206SSimon Glass };
721ca7e206SSimon Glass 
731ca7e206SSimon Glass U_BOOT_DRIVER(testbus_drv) = {
741ca7e206SSimon Glass 	.name	= "testbus_drv",
751ca7e206SSimon Glass 	.of_match	= testbus_ids,
761ca7e206SSimon Glass 	.id	= UCLASS_TEST_BUS,
771ca7e206SSimon Glass 	.probe	= testbus_drv_probe,
780118ce79SSimon Glass 	.child_post_bind = testbus_child_post_bind,
791ca7e206SSimon Glass 	.priv_auto_alloc_size = sizeof(struct dm_test_priv),
801ca7e206SSimon Glass 	.platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
81e59f458dSSimon Glass 	.per_child_auto_alloc_size = sizeof(struct dm_test_parent_data),
82cdc133bdSSimon Glass 	.per_child_platdata_auto_alloc_size =
83cdc133bdSSimon Glass 			sizeof(struct dm_test_parent_platdata),
84a327dee0SSimon Glass 	.child_pre_probe = testbus_child_pre_probe,
85a327dee0SSimon Glass 	.child_post_remove = testbus_child_post_remove,
861ca7e206SSimon Glass };
871ca7e206SSimon Glass 
881ca7e206SSimon Glass UCLASS_DRIVER(testbus) = {
891ca7e206SSimon Glass 	.name		= "testbus",
901ca7e206SSimon Glass 	.id		= UCLASS_TEST_BUS,
919cc36a2bSSimon Glass 	.flags		= DM_UC_FLAG_SEQ_ALIAS,
921ca7e206SSimon Glass };
931ca7e206SSimon Glass 
941ca7e206SSimon Glass /* Test that we can probe for children */
951ca7e206SSimon Glass static int dm_test_bus_children(struct dm_test_state *dms)
961ca7e206SSimon Glass {
979cc36a2bSSimon Glass 	int num_devices = 6;
981ca7e206SSimon Glass 	struct udevice *bus;
991ca7e206SSimon Glass 	struct uclass *uc;
1001ca7e206SSimon Glass 
1011ca7e206SSimon Glass 	ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
1021ca7e206SSimon Glass 	ut_asserteq(num_devices, list_count_items(&uc->dev_head));
1031ca7e206SSimon Glass 
1041ca7e206SSimon Glass 	/* Probe the bus, which should yield 3 more devices */
1051ca7e206SSimon Glass 	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
1061ca7e206SSimon Glass 	num_devices += 3;
1071ca7e206SSimon Glass 
1081ca7e206SSimon Glass 	ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
1091ca7e206SSimon Glass 	ut_asserteq(num_devices, list_count_items(&uc->dev_head));
1101ca7e206SSimon Glass 
1111ca7e206SSimon Glass 	ut_assert(!dm_check_devices(dms, num_devices));
1121ca7e206SSimon Glass 
1131ca7e206SSimon Glass 	return 0;
1141ca7e206SSimon Glass }
1151ca7e206SSimon Glass DM_TEST(dm_test_bus_children, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
116997c87bbSSimon Glass 
117997c87bbSSimon Glass /* Test our functions for accessing children */
118997c87bbSSimon Glass static int dm_test_bus_children_funcs(struct dm_test_state *dms)
119997c87bbSSimon Glass {
120997c87bbSSimon Glass 	const void *blob = gd->fdt_blob;
121997c87bbSSimon Glass 	struct udevice *bus, *dev;
122997c87bbSSimon Glass 	int node;
123997c87bbSSimon Glass 
124997c87bbSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
125997c87bbSSimon Glass 
126997c87bbSSimon Glass 	/* device_get_child() */
127997c87bbSSimon Glass 	ut_assertok(device_get_child(bus, 0, &dev));
128997c87bbSSimon Glass 	ut_asserteq(-ENODEV, device_get_child(bus, 4, &dev));
129997c87bbSSimon Glass 	ut_assertok(device_get_child_by_seq(bus, 5, &dev));
130997c87bbSSimon Glass 	ut_assert(dev->flags & DM_FLAG_ACTIVATED);
131997c87bbSSimon Glass 	ut_asserteq_str("c-test@5", dev->name);
132997c87bbSSimon Glass 
133997c87bbSSimon Glass 	/* Device with sequence number 0 should be accessible */
134997c87bbSSimon Glass 	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, true, &dev));
135997c87bbSSimon Glass 	ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
136997c87bbSSimon Glass 	ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
137997c87bbSSimon Glass 	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 0, false, &dev));
138997c87bbSSimon Glass 	ut_assertok(device_get_child_by_seq(bus, 0, &dev));
139997c87bbSSimon Glass 	ut_assert(dev->flags & DM_FLAG_ACTIVATED);
140997c87bbSSimon Glass 
141997c87bbSSimon Glass 	/* There is no device with sequence number 2 */
142997c87bbSSimon Glass 	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, false, &dev));
143997c87bbSSimon Glass 	ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, true, &dev));
144997c87bbSSimon Glass 	ut_asserteq(-ENODEV, device_get_child_by_seq(bus, 2, &dev));
145997c87bbSSimon Glass 
146997c87bbSSimon Glass 	/* Looking for something that is not a child */
147997c87bbSSimon Glass 	node = fdt_path_offset(blob, "/junk");
148997c87bbSSimon Glass 	ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
149997c87bbSSimon Glass 	node = fdt_path_offset(blob, "/d-test");
150997c87bbSSimon Glass 	ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
151997c87bbSSimon Glass 
152997c87bbSSimon Glass 	/* Find a valid child */
153997c87bbSSimon Glass 	node = fdt_path_offset(blob, "/some-bus/c-test@1");
154997c87bbSSimon Glass 	ut_assertok(device_find_child_by_of_offset(bus, node, &dev));
155997c87bbSSimon Glass 	ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
156997c87bbSSimon Glass 	ut_assertok(device_get_child_by_of_offset(bus, node, &dev));
157997c87bbSSimon Glass 	ut_assert(dev->flags & DM_FLAG_ACTIVATED);
158997c87bbSSimon Glass 
159997c87bbSSimon Glass 	return 0;
160997c87bbSSimon Glass }
161997c87bbSSimon Glass DM_TEST(dm_test_bus_children_funcs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
162e59f458dSSimon Glass 
163a8981d4fSSimon Glass /* Test that we can iterate through children */
164a8981d4fSSimon Glass static int dm_test_bus_children_iterators(struct dm_test_state *dms)
165a8981d4fSSimon Glass {
166a8981d4fSSimon Glass 	struct udevice *bus, *dev, *child;
167a8981d4fSSimon Glass 
168a8981d4fSSimon Glass 	/* Walk through the children one by one */
169a8981d4fSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
170a8981d4fSSimon Glass 	ut_assertok(device_find_first_child(bus, &dev));
171a8981d4fSSimon Glass 	ut_asserteq_str("c-test@5", dev->name);
172a8981d4fSSimon Glass 	ut_assertok(device_find_next_child(&dev));
173a8981d4fSSimon Glass 	ut_asserteq_str("c-test@0", dev->name);
174a8981d4fSSimon Glass 	ut_assertok(device_find_next_child(&dev));
175a8981d4fSSimon Glass 	ut_asserteq_str("c-test@1", dev->name);
176a8981d4fSSimon Glass 	ut_assertok(device_find_next_child(&dev));
177a8981d4fSSimon Glass 	ut_asserteq_ptr(dev, NULL);
178a8981d4fSSimon Glass 
179a8981d4fSSimon Glass 	/* Move to the next child without using device_find_first_child() */
180a8981d4fSSimon Glass 	ut_assertok(device_find_child_by_seq(bus, 5, true, &dev));
181a8981d4fSSimon Glass 	ut_asserteq_str("c-test@5", dev->name);
182a8981d4fSSimon Glass 	ut_assertok(device_find_next_child(&dev));
183a8981d4fSSimon Glass 	ut_asserteq_str("c-test@0", dev->name);
184a8981d4fSSimon Glass 
185a8981d4fSSimon Glass 	/* Try a device with no children */
186a8981d4fSSimon Glass 	ut_assertok(device_find_first_child(dev, &child));
187a8981d4fSSimon Glass 	ut_asserteq_ptr(child, NULL);
188a8981d4fSSimon Glass 
189a8981d4fSSimon Glass 	return 0;
190a8981d4fSSimon Glass }
191a8981d4fSSimon Glass DM_TEST(dm_test_bus_children_iterators,
192a8981d4fSSimon Glass 	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
193a8981d4fSSimon Glass 
194e59f458dSSimon Glass /* Test that the bus can store data about each child */
195*dac8db2cSSimon Glass static int test_bus_parent_data(struct dm_test_state *dms)
196e59f458dSSimon Glass {
197e59f458dSSimon Glass 	struct dm_test_parent_data *parent_data;
198e59f458dSSimon Glass 	struct udevice *bus, *dev;
199e59f458dSSimon Glass 	struct uclass *uc;
200e59f458dSSimon Glass 	int value;
201e59f458dSSimon Glass 
202e59f458dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
203e59f458dSSimon Glass 
204e59f458dSSimon Glass 	/* Check that parent data is allocated */
205e59f458dSSimon Glass 	ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
206e59f458dSSimon Glass 	ut_asserteq_ptr(NULL, dev_get_parentdata(dev));
207e59f458dSSimon Glass 	ut_assertok(device_get_child_by_seq(bus, 0, &dev));
208e59f458dSSimon Glass 	parent_data = dev_get_parentdata(dev);
209e59f458dSSimon Glass 	ut_assert(NULL != parent_data);
210e59f458dSSimon Glass 
211e59f458dSSimon Glass 	/* Check that it starts at 0 and goes away when device is removed */
212e59f458dSSimon Glass 	parent_data->sum += 5;
213e59f458dSSimon Glass 	ut_asserteq(5, parent_data->sum);
214e59f458dSSimon Glass 	device_remove(dev);
215e59f458dSSimon Glass 	ut_asserteq_ptr(NULL, dev_get_parentdata(dev));
216e59f458dSSimon Glass 
217e59f458dSSimon Glass 	/* Check that we can do this twice */
218e59f458dSSimon Glass 	ut_assertok(device_get_child_by_seq(bus, 0, &dev));
219e59f458dSSimon Glass 	parent_data = dev_get_parentdata(dev);
220e59f458dSSimon Glass 	ut_assert(NULL != parent_data);
221e59f458dSSimon Glass 	parent_data->sum += 5;
222e59f458dSSimon Glass 	ut_asserteq(5, parent_data->sum);
223e59f458dSSimon Glass 
224e59f458dSSimon Glass 	/* Add parent data to all children */
225e59f458dSSimon Glass 	ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
226e59f458dSSimon Glass 	value = 5;
227e59f458dSSimon Glass 	uclass_foreach_dev(dev, uc) {
228e59f458dSSimon Glass 		/* Ignore these if they are not on this bus */
229e59f458dSSimon Glass 		if (dev->parent != bus) {
230e59f458dSSimon Glass 			ut_asserteq_ptr(NULL, dev_get_parentdata(dev));
231e59f458dSSimon Glass 			continue;
232e59f458dSSimon Glass 		}
233e59f458dSSimon Glass 		ut_assertok(device_probe(dev));
234e59f458dSSimon Glass 		parent_data = dev_get_parentdata(dev);
235e59f458dSSimon Glass 
236e59f458dSSimon Glass 		parent_data->sum = value;
237e59f458dSSimon Glass 		value += 5;
238e59f458dSSimon Glass 	}
239e59f458dSSimon Glass 
240e59f458dSSimon Glass 	/* Check it is still there */
241e59f458dSSimon Glass 	value = 5;
242e59f458dSSimon Glass 	uclass_foreach_dev(dev, uc) {
243e59f458dSSimon Glass 		/* Ignore these if they are not on this bus */
244e59f458dSSimon Glass 		if (dev->parent != bus)
245e59f458dSSimon Glass 			continue;
246e59f458dSSimon Glass 		parent_data = dev_get_parentdata(dev);
247e59f458dSSimon Glass 
248e59f458dSSimon Glass 		ut_asserteq(value, parent_data->sum);
249e59f458dSSimon Glass 		value += 5;
250e59f458dSSimon Glass 	}
251e59f458dSSimon Glass 
252e59f458dSSimon Glass 	return 0;
253e59f458dSSimon Glass }
254*dac8db2cSSimon Glass /* Test that the bus can store data about each child */
255*dac8db2cSSimon Glass static int dm_test_bus_parent_data(struct dm_test_state *dms)
256*dac8db2cSSimon Glass {
257*dac8db2cSSimon Glass 	return test_bus_parent_data(dms);
258*dac8db2cSSimon Glass }
259e59f458dSSimon Glass DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
260a327dee0SSimon Glass 
261*dac8db2cSSimon Glass /* As above but the size is controlled by the uclass */
262*dac8db2cSSimon Glass static int dm_test_bus_parent_data_uclass(struct dm_test_state *dms)
263*dac8db2cSSimon Glass {
264*dac8db2cSSimon Glass 	struct udevice *bus;
265*dac8db2cSSimon Glass 	int size;
266*dac8db2cSSimon Glass 	int ret;
267*dac8db2cSSimon Glass 
268*dac8db2cSSimon Glass 	/* Set the driver size to 0 so that the uclass size is used */
269*dac8db2cSSimon Glass 	ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
270*dac8db2cSSimon Glass 	size = bus->driver->per_child_auto_alloc_size;
271*dac8db2cSSimon Glass 	bus->uclass->uc_drv->per_child_auto_alloc_size = size;
272*dac8db2cSSimon Glass 	bus->driver->per_child_auto_alloc_size = 0;
273*dac8db2cSSimon Glass 	ret = test_bus_parent_data(dms);
274*dac8db2cSSimon Glass 	if (ret)
275*dac8db2cSSimon Glass 		return ret;
276*dac8db2cSSimon Glass 	bus->uclass->uc_drv->per_child_auto_alloc_size = 0;
277*dac8db2cSSimon Glass 	bus->driver->per_child_auto_alloc_size = size;
278*dac8db2cSSimon Glass 
279*dac8db2cSSimon Glass 	return 0;
280*dac8db2cSSimon Glass }
281*dac8db2cSSimon Glass DM_TEST(dm_test_bus_parent_data_uclass,
282*dac8db2cSSimon Glass 	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
283*dac8db2cSSimon Glass 
284a327dee0SSimon Glass /* Test that the bus ops are called when a child is probed/removed */
285a327dee0SSimon Glass static int dm_test_bus_parent_ops(struct dm_test_state *dms)
286a327dee0SSimon Glass {
287a327dee0SSimon Glass 	struct dm_test_parent_data *parent_data;
288a327dee0SSimon Glass 	struct udevice *bus, *dev;
289a327dee0SSimon Glass 	struct uclass *uc;
290a327dee0SSimon Glass 
291a327dee0SSimon Glass 	test_state = dms;
292a327dee0SSimon Glass 	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
293a327dee0SSimon Glass 	ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
294a327dee0SSimon Glass 
295a327dee0SSimon Glass 	uclass_foreach_dev(dev, uc) {
296a327dee0SSimon Glass 		/* Ignore these if they are not on this bus */
297a327dee0SSimon Glass 		if (dev->parent != bus)
298a327dee0SSimon Glass 			continue;
299a327dee0SSimon Glass 		ut_asserteq_ptr(NULL, dev_get_parentdata(dev));
300a327dee0SSimon Glass 
301a327dee0SSimon Glass 		ut_assertok(device_probe(dev));
302a327dee0SSimon Glass 		parent_data = dev_get_parentdata(dev);
303a327dee0SSimon Glass 		ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
304a327dee0SSimon Glass 	}
305a327dee0SSimon Glass 
306a327dee0SSimon Glass 	uclass_foreach_dev(dev, uc) {
307a327dee0SSimon Glass 		/* Ignore these if they are not on this bus */
308a327dee0SSimon Glass 		if (dev->parent != bus)
309a327dee0SSimon Glass 			continue;
310a327dee0SSimon Glass 		parent_data = dev_get_parentdata(dev);
311a327dee0SSimon Glass 		ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
312a327dee0SSimon Glass 		ut_assertok(device_remove(dev));
313a327dee0SSimon Glass 		ut_asserteq_ptr(NULL, dev_get_parentdata(dev));
314a327dee0SSimon Glass 		ut_asserteq_ptr(dms->removed, dev);
315a327dee0SSimon Glass 	}
316a327dee0SSimon Glass 	test_state = NULL;
317a327dee0SSimon Glass 
318a327dee0SSimon Glass 	return 0;
319a327dee0SSimon Glass }
320a327dee0SSimon Glass DM_TEST(dm_test_bus_parent_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
321cdc133bdSSimon Glass 
322ba8da9dcSSimon Glass static int test_bus_parent_platdata(struct dm_test_state *dms)
323cdc133bdSSimon Glass {
324cdc133bdSSimon Glass 	struct dm_test_parent_platdata *plat;
325cdc133bdSSimon Glass 	struct udevice *bus, *dev;
326cdc133bdSSimon Glass 	int child_count;
327cdc133bdSSimon Glass 
328cdc133bdSSimon Glass 	/* Check that the bus has no children */
329cdc133bdSSimon Glass 	ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
330cdc133bdSSimon Glass 	device_find_first_child(bus, &dev);
331cdc133bdSSimon Glass 	ut_asserteq_ptr(NULL, dev);
332cdc133bdSSimon Glass 
333cdc133bdSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
334cdc133bdSSimon Glass 
335cdc133bdSSimon Glass 	for (device_find_first_child(bus, &dev), child_count = 0;
336cdc133bdSSimon Glass 	     dev;
337cdc133bdSSimon Glass 	     device_find_next_child(&dev)) {
338cdc133bdSSimon Glass 		/* Check that platform data is allocated */
339cdc133bdSSimon Glass 		plat = dev_get_parent_platdata(dev);
340cdc133bdSSimon Glass 		ut_assert(plat != NULL);
341cdc133bdSSimon Glass 
342cdc133bdSSimon Glass 		/*
343cdc133bdSSimon Glass 		 * Check that it is not affected by the device being
344cdc133bdSSimon Glass 		 * probed/removed
345cdc133bdSSimon Glass 		 */
346cdc133bdSSimon Glass 		plat->count++;
347cdc133bdSSimon Glass 		ut_asserteq(1, plat->count);
348cdc133bdSSimon Glass 		device_probe(dev);
349cdc133bdSSimon Glass 		device_remove(dev);
350cdc133bdSSimon Glass 
351cdc133bdSSimon Glass 		ut_asserteq_ptr(plat, dev_get_parent_platdata(dev));
352cdc133bdSSimon Glass 		ut_asserteq(1, plat->count);
353cdc133bdSSimon Glass 		ut_assertok(device_probe(dev));
354cdc133bdSSimon Glass 		child_count++;
355cdc133bdSSimon Glass 	}
356cdc133bdSSimon Glass 	ut_asserteq(3, child_count);
357cdc133bdSSimon Glass 
358cdc133bdSSimon Glass 	/* Removing the bus should also have no effect (it is still bound) */
359cdc133bdSSimon Glass 	device_remove(bus);
360cdc133bdSSimon Glass 	for (device_find_first_child(bus, &dev), child_count = 0;
361cdc133bdSSimon Glass 	     dev;
362cdc133bdSSimon Glass 	     device_find_next_child(&dev)) {
363cdc133bdSSimon Glass 		/* Check that platform data is allocated */
364cdc133bdSSimon Glass 		plat = dev_get_parent_platdata(dev);
365cdc133bdSSimon Glass 		ut_assert(plat != NULL);
366cdc133bdSSimon Glass 		ut_asserteq(1, plat->count);
367cdc133bdSSimon Glass 		child_count++;
368cdc133bdSSimon Glass 	}
369cdc133bdSSimon Glass 	ut_asserteq(3, child_count);
370cdc133bdSSimon Glass 
371cdc133bdSSimon Glass 	/* Unbind all the children */
372cdc133bdSSimon Glass 	do {
373cdc133bdSSimon Glass 		device_find_first_child(bus, &dev);
374cdc133bdSSimon Glass 		if (dev)
375cdc133bdSSimon Glass 			device_unbind(dev);
376cdc133bdSSimon Glass 	} while (dev);
377cdc133bdSSimon Glass 
378cdc133bdSSimon Glass 	/* Now the child platdata should be removed and re-added */
379cdc133bdSSimon Glass 	device_probe(bus);
380cdc133bdSSimon Glass 	for (device_find_first_child(bus, &dev), child_count = 0;
381cdc133bdSSimon Glass 	     dev;
382cdc133bdSSimon Glass 	     device_find_next_child(&dev)) {
383cdc133bdSSimon Glass 		/* Check that platform data is allocated */
384cdc133bdSSimon Glass 		plat = dev_get_parent_platdata(dev);
385cdc133bdSSimon Glass 		ut_assert(plat != NULL);
386cdc133bdSSimon Glass 		ut_asserteq(0, plat->count);
387cdc133bdSSimon Glass 		child_count++;
388cdc133bdSSimon Glass 	}
389cdc133bdSSimon Glass 	ut_asserteq(3, child_count);
390cdc133bdSSimon Glass 
391cdc133bdSSimon Glass 	return 0;
392cdc133bdSSimon Glass }
393ba8da9dcSSimon Glass 
394ba8da9dcSSimon Glass /* Test that the bus can store platform data about each child */
395ba8da9dcSSimon Glass static int dm_test_bus_parent_platdata(struct dm_test_state *dms)
396ba8da9dcSSimon Glass {
397ba8da9dcSSimon Glass 	return test_bus_parent_platdata(dms);
398ba8da9dcSSimon Glass }
399cdc133bdSSimon Glass DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
400ba8da9dcSSimon Glass 
401ba8da9dcSSimon Glass /* As above but the size is controlled by the uclass */
402ba8da9dcSSimon Glass static int dm_test_bus_parent_platdata_uclass(struct dm_test_state *dms)
403ba8da9dcSSimon Glass {
404ba8da9dcSSimon Glass 	struct udevice *bus;
405ba8da9dcSSimon Glass 	int size;
406ba8da9dcSSimon Glass 	int ret;
407ba8da9dcSSimon Glass 
408ba8da9dcSSimon Glass 	/* Set the driver size to 0 so that the uclass size is used */
409ba8da9dcSSimon Glass 	ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
410ba8da9dcSSimon Glass 	size = bus->driver->per_child_platdata_auto_alloc_size;
411ba8da9dcSSimon Glass 	bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size;
412ba8da9dcSSimon Glass 	bus->driver->per_child_platdata_auto_alloc_size = 0;
413ba8da9dcSSimon Glass 	ret = test_bus_parent_platdata(dms);
414ba8da9dcSSimon Glass 	if (ret)
415ba8da9dcSSimon Glass 		return ret;
416ba8da9dcSSimon Glass 	bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0;
417ba8da9dcSSimon Glass 	bus->driver->per_child_platdata_auto_alloc_size = size;
418ba8da9dcSSimon Glass 
419ba8da9dcSSimon Glass 	return 0;
420ba8da9dcSSimon Glass }
421ba8da9dcSSimon Glass DM_TEST(dm_test_bus_parent_platdata_uclass,
422ba8da9dcSSimon Glass 	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
4230118ce79SSimon Glass 
4240118ce79SSimon Glass /* Test that the child post_bind method is called */
4250118ce79SSimon Glass static int dm_test_bus_child_post_bind(struct dm_test_state *dms)
4260118ce79SSimon Glass {
4270118ce79SSimon Glass 	struct dm_test_parent_platdata *plat;
4280118ce79SSimon Glass 	struct udevice *bus, *dev;
4290118ce79SSimon Glass 	int child_count;
4300118ce79SSimon Glass 
4310118ce79SSimon Glass 	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
4320118ce79SSimon Glass 	for (device_find_first_child(bus, &dev), child_count = 0;
4330118ce79SSimon Glass 	     dev;
4340118ce79SSimon Glass 	     device_find_next_child(&dev)) {
4350118ce79SSimon Glass 		/* Check that platform data is allocated */
4360118ce79SSimon Glass 		plat = dev_get_parent_platdata(dev);
4370118ce79SSimon Glass 		ut_assert(plat != NULL);
4380118ce79SSimon Glass 		ut_asserteq(1, plat->bind_flag);
4390118ce79SSimon Glass 		child_count++;
4400118ce79SSimon Glass 	}
4410118ce79SSimon Glass 	ut_asserteq(3, child_count);
4420118ce79SSimon Glass 
4430118ce79SSimon Glass 	return 0;
4440118ce79SSimon Glass }
4450118ce79SSimon Glass DM_TEST(dm_test_bus_child_post_bind, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
446