blob: e9a4028f04746e955d6d98b229ba58224f8b614b [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>
7#include <dm.h>
Simon Glasse59f4582014-07-23 06:55:20 -06008#include <dm/device-internal.h>
Simon Glass1ca7e202014-07-23 06:55:18 -06009#include <dm/test.h>
Simon Glasscdc133b2015-01-25 08:27:01 -070010#include <dm/uclass-internal.h>
Simon Glass1ca7e202014-07-23 06:55:18 -060011#include <dm/util.h>
Joe Hershbergere721b882015-05-20 14:27:27 -050012#include <test/ut.h>
Simon Glass1ca7e202014-07-23 06:55:18 -060013
14DECLARE_GLOBAL_DATA_PTR;
15
Simon Glasscdc133b2015-01-25 08:27:01 -070016struct dm_test_parent_platdata {
17 int count;
Simon Glass0118ce72015-01-25 08:27:03 -070018 int bind_flag;
Simon Glass081f2fc2015-01-25 08:27:08 -070019 int uclass_bind_flag;
Simon Glasscdc133b2015-01-25 08:27:01 -070020};
21
Simon Glassa327dee2014-07-23 06:55:21 -060022enum {
23 FLAG_CHILD_PROBED = 10,
24 FLAG_CHILD_REMOVED = -7,
25};
26
27static struct dm_test_state *test_state;
28
Simon Glass1ca7e202014-07-23 06:55:18 -060029static int testbus_drv_probe(struct udevice *dev)
30{
Simon Glass2e3f1ff2016-07-05 17:10:09 -060031 return dm_scan_fdt_dev(dev);
Simon Glass1ca7e202014-07-23 06:55:18 -060032}
33
Simon Glass0118ce72015-01-25 08:27:03 -070034static int testbus_child_post_bind(struct udevice *dev)
35{
36 struct dm_test_parent_platdata *plat;
37
38 plat = dev_get_parent_platdata(dev);
39 plat->bind_flag = 1;
Simon Glass081f2fc2015-01-25 08:27:08 -070040 plat->uclass_bind_flag = 2;
Simon Glass0118ce72015-01-25 08:27:03 -070041
42 return 0;
43}
44
Simon Glassa327dee2014-07-23 06:55:21 -060045static int testbus_child_pre_probe(struct udevice *dev)
46{
Simon Glassbcbe3d12015-09-28 23:32:01 -060047 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
Simon Glassa327dee2014-07-23 06:55:21 -060048
49 parent_data->flag += FLAG_CHILD_PROBED;
50
51 return 0;
52}
53
Simon Glass83c7e432015-01-25 08:27:10 -070054static int testbus_child_pre_probe_uclass(struct udevice *dev)
55{
56 struct dm_test_priv *priv = dev_get_priv(dev);
57
58 priv->uclass_flag++;
59
60 return 0;
61}
62
Simon Glassa327dee2014-07-23 06:55:21 -060063static int testbus_child_post_remove(struct udevice *dev)
64{
Simon Glassbcbe3d12015-09-28 23:32:01 -060065 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
Simon Glassa327dee2014-07-23 06:55:21 -060066 struct dm_test_state *dms = test_state;
67
68 parent_data->flag += FLAG_CHILD_REMOVED;
69 if (dms)
70 dms->removed = dev;
71
72 return 0;
73}
74
Simon Glass1ca7e202014-07-23 06:55:18 -060075static const struct udevice_id testbus_ids[] = {
76 {
77 .compatible = "denx,u-boot-test-bus",
78 .data = DM_TEST_TYPE_FIRST },
79 { }
80};
81
82U_BOOT_DRIVER(testbus_drv) = {
83 .name = "testbus_drv",
84 .of_match = testbus_ids,
85 .id = UCLASS_TEST_BUS,
86 .probe = testbus_drv_probe,
Simon Glass0118ce72015-01-25 08:27:03 -070087 .child_post_bind = testbus_child_post_bind,
Simon Glass1ca7e202014-07-23 06:55:18 -060088 .priv_auto_alloc_size = sizeof(struct dm_test_priv),
89 .platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
Simon Glasse59f4582014-07-23 06:55:20 -060090 .per_child_auto_alloc_size = sizeof(struct dm_test_parent_data),
Simon Glasscdc133b2015-01-25 08:27:01 -070091 .per_child_platdata_auto_alloc_size =
92 sizeof(struct dm_test_parent_platdata),
Simon Glassa327dee2014-07-23 06:55:21 -060093 .child_pre_probe = testbus_child_pre_probe,
94 .child_post_remove = testbus_child_post_remove,
Simon Glass1ca7e202014-07-23 06:55:18 -060095};
96
97UCLASS_DRIVER(testbus) = {
98 .name = "testbus",
99 .id = UCLASS_TEST_BUS,
Simon Glass9cc36a22015-01-25 08:27:05 -0700100 .flags = DM_UC_FLAG_SEQ_ALIAS,
Simon Glass83c7e432015-01-25 08:27:10 -0700101 .child_pre_probe = testbus_child_pre_probe_uclass,
Simon Glass1ca7e202014-07-23 06:55:18 -0600102};
103
104/* Test that we can probe for children */
Joe Hershbergere721b882015-05-20 14:27:27 -0500105static int dm_test_bus_children(struct unit_test_state *uts)
Simon Glass1ca7e202014-07-23 06:55:18 -0600106{
Rob Clarkf2006802018-01-10 11:33:30 +0100107 int num_devices = 7;
Simon Glass1ca7e202014-07-23 06:55:18 -0600108 struct udevice *bus;
109 struct uclass *uc;
110
111 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
112 ut_asserteq(num_devices, list_count_items(&uc->dev_head));
113
114 /* Probe the bus, which should yield 3 more devices */
115 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
116 num_devices += 3;
117
118 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
119 ut_asserteq(num_devices, list_count_items(&uc->dev_head));
120
Joe Hershbergere721b882015-05-20 14:27:27 -0500121 ut_assert(!dm_check_devices(uts, num_devices));
Simon Glass1ca7e202014-07-23 06:55:18 -0600122
123 return 0;
124}
125DM_TEST(dm_test_bus_children, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass997c87b2014-07-23 06:55:19 -0600126
127/* Test our functions for accessing children */
Joe Hershbergere721b882015-05-20 14:27:27 -0500128static int dm_test_bus_children_funcs(struct unit_test_state *uts)
Simon Glass997c87b2014-07-23 06:55:19 -0600129{
130 const void *blob = gd->fdt_blob;
131 struct udevice *bus, *dev;
132 int node;
133
134 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
135
136 /* device_get_child() */
137 ut_assertok(device_get_child(bus, 0, &dev));
138 ut_asserteq(-ENODEV, device_get_child(bus, 4, &dev));
139 ut_assertok(device_get_child_by_seq(bus, 5, &dev));
140 ut_assert(dev->flags & DM_FLAG_ACTIVATED);
141 ut_asserteq_str("c-test@5", dev->name);
142
143 /* Device with sequence number 0 should be accessible */
144 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, true, &dev));
145 ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
146 ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
147 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 0, false, &dev));
148 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
149 ut_assert(dev->flags & DM_FLAG_ACTIVATED);
150
151 /* There is no device with sequence number 2 */
152 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, false, &dev));
153 ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, true, &dev));
154 ut_asserteq(-ENODEV, device_get_child_by_seq(bus, 2, &dev));
155
156 /* Looking for something that is not a child */
157 node = fdt_path_offset(blob, "/junk");
158 ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
159 node = fdt_path_offset(blob, "/d-test");
160 ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
161
Simon Glass298afb52017-05-18 20:09:43 -0600162 return 0;
163}
164DM_TEST(dm_test_bus_children_funcs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
165
166static int dm_test_bus_children_of_offset(struct unit_test_state *uts)
167{
168 const void *blob = gd->fdt_blob;
169 struct udevice *bus, *dev;
170 int node;
171
172 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
Simon Glass4f414d32017-06-07 10:28:44 -0600173 ut_assertnonnull(bus);
Simon Glass298afb52017-05-18 20:09:43 -0600174
Simon Glass997c87b2014-07-23 06:55:19 -0600175 /* Find a valid child */
176 node = fdt_path_offset(blob, "/some-bus/c-test@1");
Simon Glass298afb52017-05-18 20:09:43 -0600177 ut_assert(node > 0);
Simon Glass997c87b2014-07-23 06:55:19 -0600178 ut_assertok(device_find_child_by_of_offset(bus, node, &dev));
Simon Glass4f414d32017-06-07 10:28:44 -0600179 ut_assertnonnull(dev);
Simon Glass997c87b2014-07-23 06:55:19 -0600180 ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
181 ut_assertok(device_get_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
185 return 0;
186}
Simon Glass298afb52017-05-18 20:09:43 -0600187DM_TEST(dm_test_bus_children_of_offset,
188 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
Simon Glasse59f4582014-07-23 06:55:20 -0600189
Simon Glassa8981d42014-10-13 23:41:49 -0600190/* Test that we can iterate through children */
Joe Hershbergere721b882015-05-20 14:27:27 -0500191static int dm_test_bus_children_iterators(struct unit_test_state *uts)
Simon Glassa8981d42014-10-13 23:41:49 -0600192{
193 struct udevice *bus, *dev, *child;
194
195 /* Walk through the children one by one */
196 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
197 ut_assertok(device_find_first_child(bus, &dev));
198 ut_asserteq_str("c-test@5", dev->name);
199 ut_assertok(device_find_next_child(&dev));
200 ut_asserteq_str("c-test@0", dev->name);
201 ut_assertok(device_find_next_child(&dev));
202 ut_asserteq_str("c-test@1", dev->name);
203 ut_assertok(device_find_next_child(&dev));
204 ut_asserteq_ptr(dev, NULL);
205
206 /* Move to the next child without using device_find_first_child() */
207 ut_assertok(device_find_child_by_seq(bus, 5, true, &dev));
208 ut_asserteq_str("c-test@5", dev->name);
209 ut_assertok(device_find_next_child(&dev));
210 ut_asserteq_str("c-test@0", dev->name);
211
212 /* Try a device with no children */
213 ut_assertok(device_find_first_child(dev, &child));
214 ut_asserteq_ptr(child, NULL);
215
216 return 0;
217}
218DM_TEST(dm_test_bus_children_iterators,
219 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
220
Simon Glasse59f4582014-07-23 06:55:20 -0600221/* Test that the bus can store data about each child */
Joe Hershbergere721b882015-05-20 14:27:27 -0500222static int test_bus_parent_data(struct unit_test_state *uts)
Simon Glasse59f4582014-07-23 06:55:20 -0600223{
224 struct dm_test_parent_data *parent_data;
225 struct udevice *bus, *dev;
226 struct uclass *uc;
227 int value;
228
229 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
230
231 /* Check that parent data is allocated */
232 ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600233 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glasse59f4582014-07-23 06:55:20 -0600234 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600235 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600236 ut_assert(NULL != parent_data);
237
238 /* Check that it starts at 0 and goes away when device is removed */
239 parent_data->sum += 5;
240 ut_asserteq(5, parent_data->sum);
Stefan Roese706865a2017-03-20 12:51:48 +0100241 device_remove(dev, DM_REMOVE_NORMAL);
Simon Glassbcbe3d12015-09-28 23:32:01 -0600242 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glasse59f4582014-07-23 06:55:20 -0600243
244 /* Check that we can do this twice */
245 ut_assertok(device_get_child_by_seq(bus, 0, &dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600246 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600247 ut_assert(NULL != parent_data);
248 parent_data->sum += 5;
249 ut_asserteq(5, parent_data->sum);
250
251 /* Add parent data to all children */
252 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
253 value = 5;
254 uclass_foreach_dev(dev, uc) {
255 /* Ignore these if they are not on this bus */
256 if (dev->parent != bus) {
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 continue;
259 }
260 ut_assertok(device_probe(dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600261 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600262
263 parent_data->sum = value;
264 value += 5;
265 }
266
267 /* Check it is still there */
268 value = 5;
269 uclass_foreach_dev(dev, uc) {
270 /* Ignore these if they are not on this bus */
271 if (dev->parent != bus)
272 continue;
Simon Glassbcbe3d12015-09-28 23:32:01 -0600273 parent_data = dev_get_parent_priv(dev);
Simon Glasse59f4582014-07-23 06:55:20 -0600274
275 ut_asserteq(value, parent_data->sum);
276 value += 5;
277 }
278
279 return 0;
280}
Simon Glassdac8db22015-01-25 08:27:06 -0700281/* Test that the bus can store data about each child */
Joe Hershbergere721b882015-05-20 14:27:27 -0500282static int dm_test_bus_parent_data(struct unit_test_state *uts)
Simon Glassdac8db22015-01-25 08:27:06 -0700283{
Joe Hershbergere721b882015-05-20 14:27:27 -0500284 return test_bus_parent_data(uts);
Simon Glassdac8db22015-01-25 08:27:06 -0700285}
Simon Glasse59f4582014-07-23 06:55:20 -0600286DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glassa327dee2014-07-23 06:55:21 -0600287
Simon Glassdac8db22015-01-25 08:27:06 -0700288/* As above but the size is controlled by the uclass */
Joe Hershbergere721b882015-05-20 14:27:27 -0500289static int dm_test_bus_parent_data_uclass(struct unit_test_state *uts)
Simon Glassdac8db22015-01-25 08:27:06 -0700290{
Simon Glasse23eb612015-03-25 12:21:51 -0600291 struct driver *drv;
Simon Glassdac8db22015-01-25 08:27:06 -0700292 struct udevice *bus;
293 int size;
294 int ret;
295
296 /* Set the driver size to 0 so that the uclass size is used */
297 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
Simon Glasse23eb612015-03-25 12:21:51 -0600298 drv = (struct driver *)bus->driver;
299 size = drv->per_child_auto_alloc_size;
Simon Glassdac8db22015-01-25 08:27:06 -0700300 bus->uclass->uc_drv->per_child_auto_alloc_size = size;
Simon Glasse23eb612015-03-25 12:21:51 -0600301 drv->per_child_auto_alloc_size = 0;
Joe Hershbergere721b882015-05-20 14:27:27 -0500302 ret = test_bus_parent_data(uts);
Simon Glassdac8db22015-01-25 08:27:06 -0700303 if (ret)
304 return ret;
305 bus->uclass->uc_drv->per_child_auto_alloc_size = 0;
Simon Glasse23eb612015-03-25 12:21:51 -0600306 drv->per_child_auto_alloc_size = size;
Simon Glassdac8db22015-01-25 08:27:06 -0700307
308 return 0;
309}
310DM_TEST(dm_test_bus_parent_data_uclass,
311 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
312
Simon Glassa327dee2014-07-23 06:55:21 -0600313/* Test that the bus ops are called when a child is probed/removed */
Joe Hershbergere721b882015-05-20 14:27:27 -0500314static int dm_test_bus_parent_ops(struct unit_test_state *uts)
Simon Glassa327dee2014-07-23 06:55:21 -0600315{
316 struct dm_test_parent_data *parent_data;
Joe Hershbergere721b882015-05-20 14:27:27 -0500317 struct dm_test_state *dms = uts->priv;
Simon Glassa327dee2014-07-23 06:55:21 -0600318 struct udevice *bus, *dev;
319 struct uclass *uc;
320
321 test_state = dms;
322 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
323 ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
324
325 uclass_foreach_dev(dev, uc) {
326 /* Ignore these if they are not on this bus */
327 if (dev->parent != bus)
328 continue;
Simon Glassbcbe3d12015-09-28 23:32:01 -0600329 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glassa327dee2014-07-23 06:55:21 -0600330
331 ut_assertok(device_probe(dev));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600332 parent_data = dev_get_parent_priv(dev);
Simon Glassa327dee2014-07-23 06:55:21 -0600333 ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
334 }
335
336 uclass_foreach_dev(dev, uc) {
337 /* Ignore these if they are not on this bus */
338 if (dev->parent != bus)
339 continue;
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);
Stefan Roese706865a2017-03-20 12:51:48 +0100342 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
Simon Glassbcbe3d12015-09-28 23:32:01 -0600343 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
Simon Glassa327dee2014-07-23 06:55:21 -0600344 ut_asserteq_ptr(dms->removed, dev);
345 }
346 test_state = NULL;
347
348 return 0;
349}
350DM_TEST(dm_test_bus_parent_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glasscdc133b2015-01-25 08:27:01 -0700351
Joe Hershbergere721b882015-05-20 14:27:27 -0500352static int test_bus_parent_platdata(struct unit_test_state *uts)
Simon Glasscdc133b2015-01-25 08:27:01 -0700353{
354 struct dm_test_parent_platdata *plat;
355 struct udevice *bus, *dev;
356 int child_count;
357
358 /* Check that the bus has no children */
359 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
360 device_find_first_child(bus, &dev);
361 ut_asserteq_ptr(NULL, dev);
362
363 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
364
365 for (device_find_first_child(bus, &dev), child_count = 0;
366 dev;
367 device_find_next_child(&dev)) {
368 /* Check that platform data is allocated */
369 plat = dev_get_parent_platdata(dev);
370 ut_assert(plat != NULL);
371
372 /*
373 * Check that it is not affected by the device being
374 * probed/removed
375 */
376 plat->count++;
377 ut_asserteq(1, plat->count);
378 device_probe(dev);
Stefan Roese706865a2017-03-20 12:51:48 +0100379 device_remove(dev, DM_REMOVE_NORMAL);
Simon Glasscdc133b2015-01-25 08:27:01 -0700380
381 ut_asserteq_ptr(plat, dev_get_parent_platdata(dev));
382 ut_asserteq(1, plat->count);
383 ut_assertok(device_probe(dev));
384 child_count++;
385 }
386 ut_asserteq(3, child_count);
387
388 /* Removing the bus should also have no effect (it is still bound) */
Stefan Roese706865a2017-03-20 12:51:48 +0100389 device_remove(bus, DM_REMOVE_NORMAL);
Simon Glasscdc133b2015-01-25 08:27:01 -0700390 for (device_find_first_child(bus, &dev), child_count = 0;
391 dev;
392 device_find_next_child(&dev)) {
393 /* Check that platform data is allocated */
394 plat = dev_get_parent_platdata(dev);
395 ut_assert(plat != NULL);
396 ut_asserteq(1, plat->count);
397 child_count++;
398 }
399 ut_asserteq(3, child_count);
400
401 /* Unbind all the children */
402 do {
403 device_find_first_child(bus, &dev);
404 if (dev)
405 device_unbind(dev);
406 } while (dev);
407
408 /* Now the child platdata should be removed and re-added */
409 device_probe(bus);
410 for (device_find_first_child(bus, &dev), child_count = 0;
411 dev;
412 device_find_next_child(&dev)) {
413 /* Check that platform data is allocated */
414 plat = dev_get_parent_platdata(dev);
415 ut_assert(plat != NULL);
416 ut_asserteq(0, plat->count);
417 child_count++;
418 }
419 ut_asserteq(3, child_count);
420
421 return 0;
422}
Simon Glassba8da9d2015-01-25 08:27:02 -0700423
424/* Test that the bus can store platform data about each child */
Joe Hershbergere721b882015-05-20 14:27:27 -0500425static int dm_test_bus_parent_platdata(struct unit_test_state *uts)
Simon Glassba8da9d2015-01-25 08:27:02 -0700426{
Joe Hershbergere721b882015-05-20 14:27:27 -0500427 return test_bus_parent_platdata(uts);
Simon Glassba8da9d2015-01-25 08:27:02 -0700428}
Simon Glasscdc133b2015-01-25 08:27:01 -0700429DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glassba8da9d2015-01-25 08:27:02 -0700430
431/* As above but the size is controlled by the uclass */
Joe Hershbergere721b882015-05-20 14:27:27 -0500432static int dm_test_bus_parent_platdata_uclass(struct unit_test_state *uts)
Simon Glassba8da9d2015-01-25 08:27:02 -0700433{
434 struct udevice *bus;
Simon Glasse23eb612015-03-25 12:21:51 -0600435 struct driver *drv;
Simon Glassba8da9d2015-01-25 08:27:02 -0700436 int size;
437 int ret;
438
439 /* Set the driver size to 0 so that the uclass size is used */
440 ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
Simon Glasse23eb612015-03-25 12:21:51 -0600441 drv = (struct driver *)bus->driver;
442 size = drv->per_child_platdata_auto_alloc_size;
Simon Glassba8da9d2015-01-25 08:27:02 -0700443 bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size;
Simon Glasse23eb612015-03-25 12:21:51 -0600444 drv->per_child_platdata_auto_alloc_size = 0;
Joe Hershbergere721b882015-05-20 14:27:27 -0500445 ret = test_bus_parent_platdata(uts);
Simon Glassba8da9d2015-01-25 08:27:02 -0700446 if (ret)
447 return ret;
448 bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0;
Simon Glasse23eb612015-03-25 12:21:51 -0600449 drv->per_child_platdata_auto_alloc_size = size;
Simon Glassba8da9d2015-01-25 08:27:02 -0700450
451 return 0;
452}
453DM_TEST(dm_test_bus_parent_platdata_uclass,
454 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass0118ce72015-01-25 08:27:03 -0700455
456/* Test that the child post_bind method is called */
Joe Hershbergere721b882015-05-20 14:27:27 -0500457static int dm_test_bus_child_post_bind(struct unit_test_state *uts)
Simon Glass0118ce72015-01-25 08:27:03 -0700458{
459 struct dm_test_parent_platdata *plat;
460 struct udevice *bus, *dev;
461 int child_count;
462
463 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
464 for (device_find_first_child(bus, &dev), child_count = 0;
465 dev;
466 device_find_next_child(&dev)) {
467 /* Check that platform data is allocated */
468 plat = dev_get_parent_platdata(dev);
469 ut_assert(plat != NULL);
470 ut_asserteq(1, plat->bind_flag);
471 child_count++;
472 }
473 ut_asserteq(3, child_count);
474
475 return 0;
476}
477DM_TEST(dm_test_bus_child_post_bind, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass081f2fc2015-01-25 08:27:08 -0700478
479/* Test that the child post_bind method is called */
Joe Hershbergere721b882015-05-20 14:27:27 -0500480static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts)
Simon Glass081f2fc2015-01-25 08:27:08 -0700481{
482 struct dm_test_parent_platdata *plat;
483 struct udevice *bus, *dev;
484 int child_count;
485
486 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
487 for (device_find_first_child(bus, &dev), child_count = 0;
488 dev;
489 device_find_next_child(&dev)) {
490 /* Check that platform data is allocated */
491 plat = dev_get_parent_platdata(dev);
492 ut_assert(plat != NULL);
493 ut_asserteq(2, plat->uclass_bind_flag);
494 child_count++;
495 }
496 ut_asserteq(3, child_count);
497
498 return 0;
499}
500DM_TEST(dm_test_bus_child_post_bind_uclass,
501 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass83c7e432015-01-25 08:27:10 -0700502
503/*
504 * Test that the bus' uclass' child_pre_probe() is called before the
505 * device's probe() method
506 */
Joe Hershbergere721b882015-05-20 14:27:27 -0500507static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
Simon Glass83c7e432015-01-25 08:27:10 -0700508{
509 struct udevice *bus, *dev;
510 int child_count;
511
512 /*
513 * See testfdt_drv_probe() which effectively checks that the uclass
514 * flag is set before that method is called
515 */
516 ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
517 for (device_find_first_child(bus, &dev), child_count = 0;
518 dev;
519 device_find_next_child(&dev)) {
520 struct dm_test_priv *priv = dev_get_priv(dev);
521
522 /* Check that things happened in the right order */
523 ut_asserteq_ptr(NULL, priv);
524 ut_assertok(device_probe(dev));
525
526 priv = dev_get_priv(dev);
527 ut_assert(priv != NULL);
528 ut_asserteq(1, priv->uclass_flag);
529 ut_asserteq(1, priv->uclass_total);
530 child_count++;
531 }
532 ut_asserteq(3, child_count);
533
534 return 0;
535}
536DM_TEST(dm_test_bus_child_pre_probe_uclass,
537 DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);