test: dm: Test for default led naming
[platform/kernel/u-boot.git] / test / dm / bus.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2014 Google, Inc
4  */
5
6 #include <common.h>
7 #ifdef CONFIG_SANDBOX
8 #include <log.h>
9 #include <os.h>
10 #endif
11 #include <dm.h>
12 #include <dm/device.h>
13 #include <dm/device-internal.h>
14 #include <dm/test.h>
15 #include <dm/uclass-internal.h>
16 #include <dm/util.h>
17 #include <test/test.h>
18 #include <test/ut.h>
19
20 DECLARE_GLOBAL_DATA_PTR;
21
22 struct dm_test_parent_platdata {
23         int count;
24         int bind_flag;
25         int uclass_bind_flag;
26 };
27
28 enum {
29         FLAG_CHILD_PROBED       = 10,
30         FLAG_CHILD_REMOVED      = -7,
31 };
32
33 static struct dm_test_state *test_state;
34
35 static int testbus_drv_probe(struct udevice *dev)
36 {
37         return dm_scan_fdt_dev(dev);
38 }
39
40 static int testbus_child_post_bind(struct udevice *dev)
41 {
42         struct dm_test_parent_platdata *plat;
43
44         plat = dev_get_parent_platdata(dev);
45         plat->bind_flag = 1;
46         plat->uclass_bind_flag = 2;
47
48         return 0;
49 }
50
51 static int testbus_child_pre_probe(struct udevice *dev)
52 {
53         struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
54
55         parent_data->flag += FLAG_CHILD_PROBED;
56
57         return 0;
58 }
59
60 static int testbus_child_pre_probe_uclass(struct udevice *dev)
61 {
62         struct dm_test_priv *priv = dev_get_priv(dev);
63
64         priv->uclass_flag++;
65
66         return 0;
67 }
68
69 static int testbus_child_post_probe_uclass(struct udevice *dev)
70 {
71         struct dm_test_priv *priv = dev_get_priv(dev);
72
73         priv->uclass_postp++;
74
75         return 0;
76 }
77
78 static int testbus_child_post_remove(struct udevice *dev)
79 {
80         struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
81         struct dm_test_state *dms = test_state;
82
83         parent_data->flag += FLAG_CHILD_REMOVED;
84         if (dms)
85                 dms->removed = dev;
86
87         return 0;
88 }
89
90 static const struct udevice_id testbus_ids[] = {
91         {
92                 .compatible = "denx,u-boot-test-bus",
93                 .data = DM_TEST_TYPE_FIRST },
94         { }
95 };
96
97 U_BOOT_DRIVER(testbus_drv) = {
98         .name   = "testbus_drv",
99         .of_match       = testbus_ids,
100         .id     = UCLASS_TEST_BUS,
101         .probe  = testbus_drv_probe,
102         .child_post_bind = testbus_child_post_bind,
103         .priv_auto_alloc_size = sizeof(struct dm_test_priv),
104         .platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
105         .per_child_auto_alloc_size = sizeof(struct dm_test_parent_data),
106         .per_child_platdata_auto_alloc_size =
107                         sizeof(struct dm_test_parent_platdata),
108         .child_pre_probe = testbus_child_pre_probe,
109         .child_post_remove = testbus_child_post_remove,
110 };
111
112 UCLASS_DRIVER(testbus) = {
113         .name           = "testbus",
114         .id             = UCLASS_TEST_BUS,
115         .flags          = DM_UC_FLAG_SEQ_ALIAS,
116         .child_pre_probe = testbus_child_pre_probe_uclass,
117         .child_post_probe = testbus_child_post_probe_uclass,
118 };
119
120 /* Test that we can probe for children */
121 static int dm_test_bus_children(struct unit_test_state *uts)
122 {
123         int num_devices = 9;
124         struct udevice *bus;
125         struct uclass *uc;
126
127         ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
128         ut_asserteq(num_devices, list_count_items(&uc->dev_head));
129
130         /* Probe the bus, which should yield 3 more devices */
131         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
132         num_devices += 3;
133
134         ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
135         ut_asserteq(num_devices, list_count_items(&uc->dev_head));
136
137         ut_assert(!dm_check_devices(uts, num_devices));
138
139         return 0;
140 }
141 DM_TEST(dm_test_bus_children, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
142
143 /* Test our functions for accessing children */
144 static int dm_test_bus_children_funcs(struct unit_test_state *uts)
145 {
146         const void *blob = gd->fdt_blob;
147         struct udevice *bus, *dev;
148         int node;
149
150         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
151
152         /* device_get_child() */
153         ut_assertok(device_get_child(bus, 0, &dev));
154         ut_asserteq(-ENODEV, device_get_child(bus, 4, &dev));
155         ut_assertok(device_get_child_by_seq(bus, 5, &dev));
156         ut_assert(dev->flags & DM_FLAG_ACTIVATED);
157         ut_asserteq_str("c-test@5", dev->name);
158
159         /* Device with sequence number 0 should be accessible */
160         ut_asserteq(-ENODEV, device_find_child_by_seq(bus, -1, true, &dev));
161         ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
162         ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
163         ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 0, false, &dev));
164         ut_assertok(device_get_child_by_seq(bus, 0, &dev));
165         ut_assert(dev->flags & DM_FLAG_ACTIVATED);
166
167         /* There is no device with sequence number 2 */
168         ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, false, &dev));
169         ut_asserteq(-ENODEV, device_find_child_by_seq(bus, 2, true, &dev));
170         ut_asserteq(-ENODEV, device_get_child_by_seq(bus, 2, &dev));
171
172         /* Looking for something that is not a child */
173         node = fdt_path_offset(blob, "/junk");
174         ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
175         node = fdt_path_offset(blob, "/d-test");
176         ut_asserteq(-ENODEV, device_find_child_by_of_offset(bus, node, &dev));
177
178         return 0;
179 }
180 DM_TEST(dm_test_bus_children_funcs, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
181
182 static int dm_test_bus_children_of_offset(struct unit_test_state *uts)
183 {
184         const void *blob = gd->fdt_blob;
185         struct udevice *bus, *dev;
186         int node;
187
188         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
189         ut_assertnonnull(bus);
190
191         /* Find a valid child */
192         node = fdt_path_offset(blob, "/some-bus/c-test@1");
193         ut_assert(node > 0);
194         ut_assertok(device_find_child_by_of_offset(bus, node, &dev));
195         ut_assertnonnull(dev);
196         ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
197         ut_assertok(device_get_child_by_of_offset(bus, node, &dev));
198         ut_assertnonnull(dev);
199         ut_assert(dev->flags & DM_FLAG_ACTIVATED);
200
201         return 0;
202 }
203 DM_TEST(dm_test_bus_children_of_offset,
204         UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_FLAT_TREE);
205
206 /* Test that we can iterate through children */
207 static int dm_test_bus_children_iterators(struct unit_test_state *uts)
208 {
209         struct udevice *bus, *dev, *child;
210
211         /* Walk through the children one by one */
212         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
213         ut_assertok(device_find_first_child(bus, &dev));
214         ut_asserteq_str("c-test@5", dev->name);
215         ut_assertok(device_find_next_child(&dev));
216         ut_asserteq_str("c-test@0", dev->name);
217         ut_assertok(device_find_next_child(&dev));
218         ut_asserteq_str("c-test@1", dev->name);
219         ut_assertok(device_find_next_child(&dev));
220         ut_asserteq_ptr(dev, NULL);
221
222         /* Move to the next child without using device_find_first_child() */
223         ut_assertok(device_find_child_by_seq(bus, 5, true, &dev));
224         ut_asserteq_str("c-test@5", dev->name);
225         ut_assertok(device_find_next_child(&dev));
226         ut_asserteq_str("c-test@0", dev->name);
227
228         /* Try a device with no children */
229         ut_assertok(device_find_first_child(dev, &child));
230         ut_asserteq_ptr(child, NULL);
231
232         return 0;
233 }
234 DM_TEST(dm_test_bus_children_iterators,
235         UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
236
237 /* Test that the bus can store data about each child */
238 static int test_bus_parent_data(struct unit_test_state *uts)
239 {
240         struct dm_test_parent_data *parent_data;
241         struct udevice *bus, *dev;
242         struct uclass *uc;
243         int value;
244
245         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
246
247         /* Check that parent data is allocated */
248         ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
249         ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
250         ut_assertok(device_get_child_by_seq(bus, 0, &dev));
251         parent_data = dev_get_parent_priv(dev);
252         ut_assert(NULL != parent_data);
253
254         /* Check that it starts at 0 and goes away when device is removed */
255         parent_data->sum += 5;
256         ut_asserteq(5, parent_data->sum);
257         device_remove(dev, DM_REMOVE_NORMAL);
258         ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
259
260         /* Check that we can do this twice */
261         ut_assertok(device_get_child_by_seq(bus, 0, &dev));
262         parent_data = dev_get_parent_priv(dev);
263         ut_assert(NULL != parent_data);
264         parent_data->sum += 5;
265         ut_asserteq(5, parent_data->sum);
266
267         /* Add parent data to all children */
268         ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
269         value = 5;
270         uclass_foreach_dev(dev, uc) {
271                 /* Ignore these if they are not on this bus */
272                 if (dev->parent != bus) {
273                         ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
274                         continue;
275                 }
276                 ut_assertok(device_probe(dev));
277                 parent_data = dev_get_parent_priv(dev);
278
279                 parent_data->sum = value;
280                 value += 5;
281         }
282
283         /* Check it is still there */
284         value = 5;
285         uclass_foreach_dev(dev, uc) {
286                 /* Ignore these if they are not on this bus */
287                 if (dev->parent != bus)
288                         continue;
289                 parent_data = dev_get_parent_priv(dev);
290
291                 ut_asserteq(value, parent_data->sum);
292                 value += 5;
293         }
294
295         return 0;
296 }
297 /* Test that the bus can store data about each child */
298 static int dm_test_bus_parent_data(struct unit_test_state *uts)
299 {
300         return test_bus_parent_data(uts);
301 }
302 DM_TEST(dm_test_bus_parent_data, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
303
304 /* As above but the size is controlled by the uclass */
305 static int dm_test_bus_parent_data_uclass(struct unit_test_state *uts)
306 {
307         struct driver *drv;
308         struct udevice *bus;
309         int size;
310         int ret;
311
312         /* Set the driver size to 0 so that the uclass size is used */
313         ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
314         drv = (struct driver *)bus->driver;
315         size = drv->per_child_auto_alloc_size;
316
317 #ifdef CONFIG_SANDBOX
318         os_mprotect_allow(bus->uclass->uc_drv, sizeof(*bus->uclass->uc_drv));
319         os_mprotect_allow(drv, sizeof(*drv));
320 #endif
321         bus->uclass->uc_drv->per_child_auto_alloc_size = size;
322         drv->per_child_auto_alloc_size = 0;
323         ret = test_bus_parent_data(uts);
324         if (ret)
325                 return ret;
326         bus->uclass->uc_drv->per_child_auto_alloc_size = 0;
327         drv->per_child_auto_alloc_size = size;
328
329         return 0;
330 }
331 DM_TEST(dm_test_bus_parent_data_uclass,
332         UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
333
334 /* Test that the bus ops are called when a child is probed/removed */
335 static int dm_test_bus_parent_ops(struct unit_test_state *uts)
336 {
337         struct dm_test_parent_data *parent_data;
338         struct dm_test_state *dms = uts->priv;
339         struct udevice *bus, *dev;
340         struct uclass *uc;
341
342         test_state = dms;
343         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
344         ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
345
346         uclass_foreach_dev(dev, uc) {
347                 /* Ignore these if they are not on this bus */
348                 if (dev->parent != bus)
349                         continue;
350                 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
351
352                 ut_assertok(device_probe(dev));
353                 parent_data = dev_get_parent_priv(dev);
354                 ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
355         }
356
357         uclass_foreach_dev(dev, uc) {
358                 /* Ignore these if they are not on this bus */
359                 if (dev->parent != bus)
360                         continue;
361                 parent_data = dev_get_parent_priv(dev);
362                 ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
363                 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
364                 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
365                 ut_asserteq_ptr(dms->removed, dev);
366         }
367         test_state = NULL;
368
369         return 0;
370 }
371 DM_TEST(dm_test_bus_parent_ops, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
372
373 static int test_bus_parent_platdata(struct unit_test_state *uts)
374 {
375         struct dm_test_parent_platdata *plat;
376         struct udevice *bus, *dev;
377
378         /* Check that the bus has no children */
379         ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
380         device_find_first_child(bus, &dev);
381         ut_asserteq_ptr(NULL, dev);
382
383         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
384
385         for (device_find_first_child(bus, &dev);
386              dev;
387              device_find_next_child(&dev)) {
388                 /* Check that platform data is allocated */
389                 plat = dev_get_parent_platdata(dev);
390                 ut_assert(plat != NULL);
391
392                 /*
393                  * Check that it is not affected by the device being
394                  * probed/removed
395                  */
396                 plat->count++;
397                 ut_asserteq(1, plat->count);
398                 device_probe(dev);
399                 device_remove(dev, DM_REMOVE_NORMAL);
400
401                 ut_asserteq_ptr(plat, dev_get_parent_platdata(dev));
402                 ut_asserteq(1, plat->count);
403                 ut_assertok(device_probe(dev));
404         }
405         ut_asserteq(3, device_get_child_count(bus));
406
407         /* Removing the bus should also have no effect (it is still bound) */
408         device_remove(bus, DM_REMOVE_NORMAL);
409         for (device_find_first_child(bus, &dev);
410              dev;
411              device_find_next_child(&dev)) {
412                 /* Check that platform data is allocated */
413                 plat = dev_get_parent_platdata(dev);
414                 ut_assert(plat != NULL);
415                 ut_asserteq(1, plat->count);
416         }
417         ut_asserteq(3, device_get_child_count(bus));
418
419         /* Unbind all the children */
420         do {
421                 device_find_first_child(bus, &dev);
422                 if (dev)
423                         device_unbind(dev);
424         } while (dev);
425
426         /* Now the child platdata should be removed and re-added */
427         device_probe(bus);
428         for (device_find_first_child(bus, &dev);
429              dev;
430              device_find_next_child(&dev)) {
431                 /* Check that platform data is allocated */
432                 plat = dev_get_parent_platdata(dev);
433                 ut_assert(plat != NULL);
434                 ut_asserteq(0, plat->count);
435         }
436         ut_asserteq(3, device_get_child_count(bus));
437
438         return 0;
439 }
440
441 /* Test that the bus can store platform data about each child */
442 static int dm_test_bus_parent_platdata(struct unit_test_state *uts)
443 {
444         return test_bus_parent_platdata(uts);
445 }
446 DM_TEST(dm_test_bus_parent_platdata, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
447
448 /* As above but the size is controlled by the uclass */
449 static int dm_test_bus_parent_platdata_uclass(struct unit_test_state *uts)
450 {
451         struct udevice *bus;
452         struct driver *drv;
453         int size;
454         int ret;
455
456         /* Set the driver size to 0 so that the uclass size is used */
457         ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
458         drv = (struct driver *)bus->driver;
459         size = drv->per_child_platdata_auto_alloc_size;
460 #ifdef CONFIG_SANDBOX
461         os_mprotect_allow(bus->uclass->uc_drv, sizeof(*bus->uclass->uc_drv));
462         os_mprotect_allow(drv, sizeof(*drv));
463 #endif
464         bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size;
465         drv->per_child_platdata_auto_alloc_size = 0;
466         ret = test_bus_parent_platdata(uts);
467         if (ret)
468                 return ret;
469         bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0;
470         drv->per_child_platdata_auto_alloc_size = size;
471
472         return 0;
473 }
474 DM_TEST(dm_test_bus_parent_platdata_uclass,
475         UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
476
477 /* Test that the child post_bind method is called */
478 static int dm_test_bus_child_post_bind(struct unit_test_state *uts)
479 {
480         struct dm_test_parent_platdata *plat;
481         struct udevice *bus, *dev;
482
483         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
484         for (device_find_first_child(bus, &dev);
485              dev;
486              device_find_next_child(&dev)) {
487                 /* Check that platform data is allocated */
488                 plat = dev_get_parent_platdata(dev);
489                 ut_assert(plat != NULL);
490                 ut_asserteq(1, plat->bind_flag);
491         }
492         ut_asserteq(3, device_get_child_count(bus));
493
494         return 0;
495 }
496 DM_TEST(dm_test_bus_child_post_bind, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
497
498 /* Test that the child post_bind method is called */
499 static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts)
500 {
501         struct dm_test_parent_platdata *plat;
502         struct udevice *bus, *dev;
503
504         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
505         for (device_find_first_child(bus, &dev);
506              dev;
507              device_find_next_child(&dev)) {
508                 /* Check that platform data is allocated */
509                 plat = dev_get_parent_platdata(dev);
510                 ut_assert(plat != NULL);
511                 ut_asserteq(2, plat->uclass_bind_flag);
512         }
513         ut_asserteq(3, device_get_child_count(bus));
514
515         return 0;
516 }
517 DM_TEST(dm_test_bus_child_post_bind_uclass,
518         UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
519
520 /*
521  * Test that the bus' uclass' child_pre_probe() is called before the
522  * device's probe() method
523  */
524 static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
525 {
526         struct udevice *bus, *dev;
527
528         /*
529          * See testfdt_drv_probe() which effectively checks that the uclass
530          * flag is set before that method is called
531          */
532         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
533         for (device_find_first_child(bus, &dev);
534              dev;
535              device_find_next_child(&dev)) {
536                 struct dm_test_priv *priv = dev_get_priv(dev);
537
538                 /* Check that things happened in the right order */
539                 ut_asserteq_ptr(NULL, priv);
540                 ut_assertok(device_probe(dev));
541
542                 priv = dev_get_priv(dev);
543                 ut_assert(priv != NULL);
544                 ut_asserteq(1, priv->uclass_flag);
545                 ut_asserteq(1, priv->uclass_total);
546         }
547         ut_asserteq(3, device_get_child_count(bus));
548
549         return 0;
550 }
551 DM_TEST(dm_test_bus_child_pre_probe_uclass,
552         UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
553
554 /*
555  * Test that the bus' uclass' child_post_probe() is called after the
556  * device's probe() method
557  */
558 static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts)
559 {
560         struct udevice *bus, *dev;
561
562         /*
563          * See testfdt_drv_probe() which effectively initializes that
564          * the uclass postp flag is set to a value
565          */
566         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
567         for (device_find_first_child(bus, &dev);
568              dev;
569              device_find_next_child(&dev)) {
570                 struct dm_test_priv *priv = dev_get_priv(dev);
571
572                 /* Check that things happened in the right order */
573                 ut_asserteq_ptr(NULL, priv);
574                 ut_assertok(device_probe(dev));
575
576                 priv = dev_get_priv(dev);
577                 ut_assert(priv != NULL);
578                 ut_asserteq(0, priv->uclass_postp);
579         }
580         ut_asserteq(3, device_get_child_count(bus));
581
582         return 0;
583 }
584 DM_TEST(dm_test_bus_child_post_probe_uclass,
585         UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);