blob: 80900e416ba8832eb426cb5244cdd6d7d34e5a23 [file] [log] [blame]
Simon Glass217293e2020-10-25 20:38:29 -06001// SPDX-License-Identifier: GPL-2.0+
2
3#include <common.h>
4#include <dm.h>
Simon Glassb3252482020-10-03 11:31:28 -06005#include <dt-structs.h>
Simon Glass217293e2020-10-25 20:38:29 -06006#include <dm/test.h>
7#include <test/test.h>
8#include <test/ut.h>
9
10/* Test that we can find a device using of-platdata */
11static int dm_test_of_platdata_base(struct unit_test_state *uts)
12{
13 struct udevice *dev;
14
15 ut_assertok(uclass_first_device_err(UCLASS_SERIAL, &dev));
16 ut_asserteq_str("sandbox_serial", dev->name);
17
18 return 0;
19}
20DM_TEST(dm_test_of_platdata_base, UT_TESTF_SCAN_PDATA);
Simon Glassb3252482020-10-03 11:31:28 -060021
22/* Test that we can read properties from a device */
23static int dm_test_of_platdata_props(struct unit_test_state *uts)
24{
25 struct dtd_sandbox_spl_test *plat;
26 struct udevice *dev;
27 int i;
28
29 ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
30 plat = dev_get_platdata(dev);
31 ut_assert(plat->boolval);
32 ut_asserteq(1, plat->intval);
33 ut_asserteq(4, ARRAY_SIZE(plat->intarray));
34 ut_asserteq(2, plat->intarray[0]);
35 ut_asserteq(3, plat->intarray[1]);
36 ut_asserteq(4, plat->intarray[2]);
37 ut_asserteq(0, plat->intarray[3]);
38 ut_asserteq(5, plat->byteval);
39 ut_asserteq(3, ARRAY_SIZE(plat->bytearray));
40 ut_asserteq(6, plat->bytearray[0]);
41 ut_asserteq(0, plat->bytearray[1]);
42 ut_asserteq(0, plat->bytearray[2]);
43 ut_asserteq(9, ARRAY_SIZE(plat->longbytearray));
44 for (i = 0; i < ARRAY_SIZE(plat->longbytearray); i++)
45 ut_asserteq(9 + i, plat->longbytearray[i]);
46 ut_asserteq_str("message", plat->stringval);
47 ut_asserteq(3, ARRAY_SIZE(plat->stringarray));
48 ut_asserteq_str("multi-word", plat->stringarray[0]);
49 ut_asserteq_str("message", plat->stringarray[1]);
50 ut_asserteq_str("", plat->stringarray[2]);
51
52 ut_assertok(uclass_next_device_err(&dev));
53 plat = dev_get_platdata(dev);
54 ut_assert(!plat->boolval);
55 ut_asserteq(3, plat->intval);
56 ut_asserteq(5, plat->intarray[0]);
57 ut_asserteq(0, plat->intarray[1]);
58 ut_asserteq(0, plat->intarray[2]);
59 ut_asserteq(0, plat->intarray[3]);
60 ut_asserteq(8, plat->byteval);
61 ut_asserteq(3, ARRAY_SIZE(plat->bytearray));
62 ut_asserteq(1, plat->bytearray[0]);
63 ut_asserteq(0x23, plat->bytearray[1]);
64 ut_asserteq(0x34, plat->bytearray[2]);
65 for (i = 0; i < ARRAY_SIZE(plat->longbytearray); i++)
66 ut_asserteq(i < 4 ? 9 + i : 0, plat->longbytearray[i]);
67 ut_asserteq_str("message2", plat->stringval);
68 ut_asserteq_str("another", plat->stringarray[0]);
69 ut_asserteq_str("multi-word", plat->stringarray[1]);
70 ut_asserteq_str("message", plat->stringarray[2]);
71
72 ut_assertok(uclass_next_device_err(&dev));
73 plat = dev_get_platdata(dev);
74 ut_assert(!plat->boolval);
75 ut_asserteq_str("one", plat->stringarray[0]);
76 ut_asserteq_str("", plat->stringarray[1]);
77 ut_asserteq_str("", plat->stringarray[2]);
78
79 ut_assertok(uclass_next_device_err(&dev));
80 plat = dev_get_platdata(dev);
81 ut_assert(!plat->boolval);
82 ut_asserteq_str("spl", plat->stringarray[0]);
83
84 ut_asserteq(-ENODEV, uclass_next_device_err(&dev));
85
86 return 0;
87}
88DM_TEST(dm_test_of_platdata_props, UT_TESTF_SCAN_PDATA);
Simon Glass36af37b2020-10-03 11:31:31 -060089
90/*
91 * find_driver_info - recursively find the driver_info for a device
92 *
93 * This sets found[idx] to true when it finds the driver_info record for a
94 * device, where idx is the index in the driver_info linker list.
95 *
96 * @uts: Test state
97 * @parent: Parent to search
98 * @found: bool array to update
99 * @return 0 if OK, non-zero on error
100 */
101static int find_driver_info(struct unit_test_state *uts, struct udevice *parent,
102 bool found[])
103{
104 struct udevice *dev;
105
106 /* If not the root device, find the entry that caused it to be bound */
107 if (parent->parent) {
108 const struct driver_info *info =
109 ll_entry_start(struct driver_info, driver_info);
110 const int n_ents =
111 ll_entry_count(struct driver_info, driver_info);
112 const struct driver_info *entry;
113 int idx = -1;
114
115 for (entry = info; entry != info + n_ents; entry++) {
116 if (entry->dev == parent) {
117 idx = entry - info;
118 found[idx] = true;
119 break;
120 }
121 }
122
123 ut_assert(idx != -1);
124 }
125
126 device_foreach_child(dev, parent) {
127 int ret;
128
129 ret = find_driver_info(uts, dev, found);
130 if (ret < 0)
131 return ret;
132 }
133
134 return 0;
135}
136
137/* Check that every device is recorded in its driver_info struct */
138static int dm_test_of_platdata_dev(struct unit_test_state *uts)
139{
140 const struct driver_info *info =
141 ll_entry_start(struct driver_info, driver_info);
142 const int n_ents = ll_entry_count(struct driver_info, driver_info);
143 bool found[n_ents];
144 uint i;
145
146 /* Record the indexes that are found */
147 memset(found, '\0', sizeof(found));
148 ut_assertok(find_driver_info(uts, gd->dm_root, found));
149
150 /* Make sure that the driver entries without devices have no ->dev */
151 for (i = 0; i < n_ents; i++) {
152 const struct driver_info *entry = info + i;
153 struct udevice *dev;
154
155 if (found[i]) {
156 /* Make sure we can find it */
157 ut_assertnonnull(entry->dev);
158 ut_assertok(device_get_by_driver_info(entry, &dev));
159 ut_asserteq_ptr(dev, entry->dev);
160 } else {
161 ut_assertnull(entry->dev);
162 ut_asserteq(-ENOENT,
163 device_get_by_driver_info(entry, &dev));
164 }
165 }
166
167 return 0;
168}
169DM_TEST(dm_test_of_platdata_dev, UT_TESTF_SCAN_PDATA);