common: Drop log.h from common header
[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/ut.h>
18
19 DECLARE_GLOBAL_DATA_PTR;
20
21 struct dm_test_parent_platdata {
22         int count;
23         int bind_flag;
24         int uclass_bind_flag;
25 };
26
27 enum {
28         FLAG_CHILD_PROBED       = 10,
29         FLAG_CHILD_REMOVED      = -7,
30 };
31
32 static struct dm_test_state *test_state;
33
34 static int testbus_drv_probe(struct udevice *dev)
35 {
36         return dm_scan_fdt_dev(dev);
37 }
38
39 static 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;
45         plat->uclass_bind_flag = 2;
46
47         return 0;
48 }
49
50 static int testbus_child_pre_probe(struct udevice *dev)
51 {
52         struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
53
54         parent_data->flag += FLAG_CHILD_PROBED;
55
56         return 0;
57 }
58
59 static 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
68 static 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
77 static int testbus_child_post_remove(struct udevice *dev)
78 {
79         struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
80         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
89 static const struct udevice_id testbus_ids[] = {
90         {
91                 .compatible = "denx,u-boot-test-bus",
92                 .data = DM_TEST_TYPE_FIRST },
93         { }
94 };
95
96 U_BOOT_DRIVER(testbus_drv) = {
97         .name   = "testbus_drv",
98         .of_match       = testbus_ids,
99         .id     = UCLASS_TEST_BUS,
100         .probe  = testbus_drv_probe,
101         .child_post_bind = testbus_child_post_bind,
102         .priv_auto_alloc_size = sizeof(struct dm_test_priv),
103         .platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
104         .per_child_auto_alloc_size = sizeof(struct dm_test_parent_data),
105         .per_child_platdata_auto_alloc_size =
106                         sizeof(struct dm_test_parent_platdata),
107         .child_pre_probe = testbus_child_pre_probe,
108         .child_post_remove = testbus_child_post_remove,
109 };
110
111 UCLASS_DRIVER(testbus) = {
112         .name           = "testbus",
113         .id             = UCLASS_TEST_BUS,
114         .flags          = DM_UC_FLAG_SEQ_ALIAS,
115         .child_pre_probe = testbus_child_pre_probe_uclass,
116         .child_post_probe = testbus_child_post_probe_uclass,
117 };
118
119 /* Test that we can probe for children */
120 static int dm_test_bus_children(struct unit_test_state *uts)
121 {
122         int num_devices = 8;
123         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
136         ut_assert(!dm_check_devices(uts, num_devices));
137
138         return 0;
139 }
140 DM_TEST(dm_test_bus_children, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
141
142 /* Test our functions for accessing children */
143 static int dm_test_bus_children_funcs(struct unit_test_state *uts)
144 {
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
177         return 0;
178 }
179 DM_TEST(dm_test_bus_children_funcs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
180
181 static 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));
188         ut_assertnonnull(bus);
189
190         /* Find a valid child */
191         node = fdt_path_offset(blob, "/some-bus/c-test@1");
192         ut_assert(node > 0);
193         ut_assertok(device_find_child_by_of_offset(bus, node, &dev));
194         ut_assertnonnull(dev);
195         ut_assert(!(dev->flags & DM_FLAG_ACTIVATED));
196         ut_assertok(device_get_child_by_of_offset(bus, node, &dev));
197         ut_assertnonnull(dev);
198         ut_assert(dev->flags & DM_FLAG_ACTIVATED);
199
200         return 0;
201 }
202 DM_TEST(dm_test_bus_children_of_offset,
203         DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT | DM_TESTF_FLAT_TREE);
204
205 /* Test that we can iterate through children */
206 static int dm_test_bus_children_iterators(struct unit_test_state *uts)
207 {
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 }
233 DM_TEST(dm_test_bus_children_iterators,
234         DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
235
236 /* Test that the bus can store data about each child */
237 static int test_bus_parent_data(struct unit_test_state *uts)
238 {
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));
248         ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
249         ut_assertok(device_get_child_by_seq(bus, 0, &dev));
250         parent_data = dev_get_parent_priv(dev);
251         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);
256         device_remove(dev, DM_REMOVE_NORMAL);
257         ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
258
259         /* Check that we can do this twice */
260         ut_assertok(device_get_child_by_seq(bus, 0, &dev));
261         parent_data = dev_get_parent_priv(dev);
262         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) {
272                         ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
273                         continue;
274                 }
275                 ut_assertok(device_probe(dev));
276                 parent_data = dev_get_parent_priv(dev);
277
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;
288                 parent_data = dev_get_parent_priv(dev);
289
290                 ut_asserteq(value, parent_data->sum);
291                 value += 5;
292         }
293
294         return 0;
295 }
296 /* Test that the bus can store data about each child */
297 static int dm_test_bus_parent_data(struct unit_test_state *uts)
298 {
299         return test_bus_parent_data(uts);
300 }
301 DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
302
303 /* As above but the size is controlled by the uclass */
304 static int dm_test_bus_parent_data_uclass(struct unit_test_state *uts)
305 {
306         struct driver *drv;
307         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));
313         drv = (struct driver *)bus->driver;
314         size = drv->per_child_auto_alloc_size;
315
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
320         bus->uclass->uc_drv->per_child_auto_alloc_size = size;
321         drv->per_child_auto_alloc_size = 0;
322         ret = test_bus_parent_data(uts);
323         if (ret)
324                 return ret;
325         bus->uclass->uc_drv->per_child_auto_alloc_size = 0;
326         drv->per_child_auto_alloc_size = size;
327
328         return 0;
329 }
330 DM_TEST(dm_test_bus_parent_data_uclass,
331         DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
332
333 /* Test that the bus ops are called when a child is probed/removed */
334 static int dm_test_bus_parent_ops(struct unit_test_state *uts)
335 {
336         struct dm_test_parent_data *parent_data;
337         struct dm_test_state *dms = uts->priv;
338         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;
349                 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
350
351                 ut_assertok(device_probe(dev));
352                 parent_data = dev_get_parent_priv(dev);
353                 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;
360                 parent_data = dev_get_parent_priv(dev);
361                 ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
362                 ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
363                 ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
364                 ut_asserteq_ptr(dms->removed, dev);
365         }
366         test_state = NULL;
367
368         return 0;
369 }
370 DM_TEST(dm_test_bus_parent_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
371
372 static int test_bus_parent_platdata(struct unit_test_state *uts)
373 {
374         struct dm_test_parent_platdata *plat;
375         struct udevice *bus, *dev;
376
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
384         for (device_find_first_child(bus, &dev);
385              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);
398                 device_remove(dev, DM_REMOVE_NORMAL);
399
400                 ut_asserteq_ptr(plat, dev_get_parent_platdata(dev));
401                 ut_asserteq(1, plat->count);
402                 ut_assertok(device_probe(dev));
403         }
404         ut_asserteq(3, device_get_child_count(bus));
405
406         /* Removing the bus should also have no effect (it is still bound) */
407         device_remove(bus, DM_REMOVE_NORMAL);
408         for (device_find_first_child(bus, &dev);
409              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);
415         }
416         ut_asserteq(3, device_get_child_count(bus));
417
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);
427         for (device_find_first_child(bus, &dev);
428              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);
434         }
435         ut_asserteq(3, device_get_child_count(bus));
436
437         return 0;
438 }
439
440 /* Test that the bus can store platform data about each child */
441 static int dm_test_bus_parent_platdata(struct unit_test_state *uts)
442 {
443         return test_bus_parent_platdata(uts);
444 }
445 DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
446
447 /* As above but the size is controlled by the uclass */
448 static int dm_test_bus_parent_platdata_uclass(struct unit_test_state *uts)
449 {
450         struct udevice *bus;
451         struct driver *drv;
452         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));
457         drv = (struct driver *)bus->driver;
458         size = drv->per_child_platdata_auto_alloc_size;
459 #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
463         bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size;
464         drv->per_child_platdata_auto_alloc_size = 0;
465         ret = test_bus_parent_platdata(uts);
466         if (ret)
467                 return ret;
468         bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0;
469         drv->per_child_platdata_auto_alloc_size = size;
470
471         return 0;
472 }
473 DM_TEST(dm_test_bus_parent_platdata_uclass,
474         DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
475
476 /* Test that the child post_bind method is called */
477 static int dm_test_bus_child_post_bind(struct unit_test_state *uts)
478 {
479         struct dm_test_parent_platdata *plat;
480         struct udevice *bus, *dev;
481
482         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
483         for (device_find_first_child(bus, &dev);
484              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);
490         }
491         ut_asserteq(3, device_get_child_count(bus));
492
493         return 0;
494 }
495 DM_TEST(dm_test_bus_child_post_bind, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
496
497 /* Test that the child post_bind method is called */
498 static int dm_test_bus_child_post_bind_uclass(struct unit_test_state *uts)
499 {
500         struct dm_test_parent_platdata *plat;
501         struct udevice *bus, *dev;
502
503         ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
504         for (device_find_first_child(bus, &dev);
505              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);
511         }
512         ut_asserteq(3, device_get_child_count(bus));
513
514         return 0;
515 }
516 DM_TEST(dm_test_bus_child_post_bind_uclass,
517         DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
518
519 /*
520  * Test that the bus' uclass' child_pre_probe() is called before the
521  * device's probe() method
522  */
523 static int dm_test_bus_child_pre_probe_uclass(struct unit_test_state *uts)
524 {
525         struct udevice *bus, *dev;
526
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));
532         for (device_find_first_child(bus, &dev);
533              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);
545         }
546         ut_asserteq(3, device_get_child_count(bus));
547
548         return 0;
549 }
550 DM_TEST(dm_test_bus_child_pre_probe_uclass,
551         DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
552
553 /*
554  * Test that the bus' uclass' child_post_probe() is called after the
555  * device's probe() method
556  */
557 static int dm_test_bus_child_post_probe_uclass(struct unit_test_state *uts)
558 {
559         struct udevice *bus, *dev;
560
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));
566         for (device_find_first_child(bus, &dev);
567              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);
578         }
579         ut_asserteq(3, device_get_child_count(bus));
580
581         return 0;
582 }
583 DM_TEST(dm_test_bus_child_post_probe_uclass,
584         DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);