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