blob: 57f903611a687b96c903009c3eeeae73099fe731 [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
Simon Glass88280522020-10-03 11:31:32 -060029 /* Skip the clock */
Simon Glassb3252482020-10-03 11:31:28 -060030 ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
Simon Glass88280522020-10-03 11:31:32 -060031 ut_asserteq_str("sandbox_clk_test", dev->name);
32
33 ut_assertok(uclass_next_device_err(&dev));
Simon Glassb3252482020-10-03 11:31:28 -060034 plat = dev_get_platdata(dev);
35 ut_assert(plat->boolval);
36 ut_asserteq(1, plat->intval);
37 ut_asserteq(4, ARRAY_SIZE(plat->intarray));
38 ut_asserteq(2, plat->intarray[0]);
39 ut_asserteq(3, plat->intarray[1]);
40 ut_asserteq(4, plat->intarray[2]);
41 ut_asserteq(0, plat->intarray[3]);
42 ut_asserteq(5, plat->byteval);
43 ut_asserteq(3, ARRAY_SIZE(plat->bytearray));
44 ut_asserteq(6, plat->bytearray[0]);
45 ut_asserteq(0, plat->bytearray[1]);
46 ut_asserteq(0, plat->bytearray[2]);
47 ut_asserteq(9, ARRAY_SIZE(plat->longbytearray));
48 for (i = 0; i < ARRAY_SIZE(plat->longbytearray); i++)
49 ut_asserteq(9 + i, plat->longbytearray[i]);
50 ut_asserteq_str("message", plat->stringval);
51 ut_asserteq(3, ARRAY_SIZE(plat->stringarray));
52 ut_asserteq_str("multi-word", plat->stringarray[0]);
53 ut_asserteq_str("message", plat->stringarray[1]);
54 ut_asserteq_str("", plat->stringarray[2]);
55
56 ut_assertok(uclass_next_device_err(&dev));
57 plat = dev_get_platdata(dev);
58 ut_assert(!plat->boolval);
59 ut_asserteq(3, plat->intval);
60 ut_asserteq(5, plat->intarray[0]);
61 ut_asserteq(0, plat->intarray[1]);
62 ut_asserteq(0, plat->intarray[2]);
63 ut_asserteq(0, plat->intarray[3]);
64 ut_asserteq(8, plat->byteval);
65 ut_asserteq(3, ARRAY_SIZE(plat->bytearray));
66 ut_asserteq(1, plat->bytearray[0]);
67 ut_asserteq(0x23, plat->bytearray[1]);
68 ut_asserteq(0x34, plat->bytearray[2]);
69 for (i = 0; i < ARRAY_SIZE(plat->longbytearray); i++)
70 ut_asserteq(i < 4 ? 9 + i : 0, plat->longbytearray[i]);
71 ut_asserteq_str("message2", plat->stringval);
72 ut_asserteq_str("another", plat->stringarray[0]);
73 ut_asserteq_str("multi-word", plat->stringarray[1]);
74 ut_asserteq_str("message", plat->stringarray[2]);
75
76 ut_assertok(uclass_next_device_err(&dev));
77 plat = dev_get_platdata(dev);
78 ut_assert(!plat->boolval);
79 ut_asserteq_str("one", plat->stringarray[0]);
80 ut_asserteq_str("", plat->stringarray[1]);
81 ut_asserteq_str("", plat->stringarray[2]);
82
83 ut_assertok(uclass_next_device_err(&dev));
84 plat = dev_get_platdata(dev);
85 ut_assert(!plat->boolval);
86 ut_asserteq_str("spl", plat->stringarray[0]);
87
88 ut_asserteq(-ENODEV, uclass_next_device_err(&dev));
89
90 return 0;
91}
92DM_TEST(dm_test_of_platdata_props, UT_TESTF_SCAN_PDATA);
Simon Glass36af37b2020-10-03 11:31:31 -060093
94/*
95 * find_driver_info - recursively find the driver_info for a device
96 *
97 * This sets found[idx] to true when it finds the driver_info record for a
98 * device, where idx is the index in the driver_info linker list.
99 *
100 * @uts: Test state
101 * @parent: Parent to search
102 * @found: bool array to update
103 * @return 0 if OK, non-zero on error
104 */
105static int find_driver_info(struct unit_test_state *uts, struct udevice *parent,
106 bool found[])
107{
108 struct udevice *dev;
109
110 /* If not the root device, find the entry that caused it to be bound */
111 if (parent->parent) {
112 const struct driver_info *info =
113 ll_entry_start(struct driver_info, driver_info);
114 const int n_ents =
115 ll_entry_count(struct driver_info, driver_info);
116 const struct driver_info *entry;
117 int idx = -1;
118
119 for (entry = info; entry != info + n_ents; entry++) {
120 if (entry->dev == parent) {
121 idx = entry - info;
122 found[idx] = true;
123 break;
124 }
125 }
126
127 ut_assert(idx != -1);
128 }
129
130 device_foreach_child(dev, parent) {
131 int ret;
132
133 ret = find_driver_info(uts, dev, found);
134 if (ret < 0)
135 return ret;
136 }
137
138 return 0;
139}
140
141/* Check that every device is recorded in its driver_info struct */
142static int dm_test_of_platdata_dev(struct unit_test_state *uts)
143{
144 const struct driver_info *info =
145 ll_entry_start(struct driver_info, driver_info);
146 const int n_ents = ll_entry_count(struct driver_info, driver_info);
147 bool found[n_ents];
148 uint i;
149
150 /* Record the indexes that are found */
151 memset(found, '\0', sizeof(found));
152 ut_assertok(find_driver_info(uts, gd->dm_root, found));
153
154 /* Make sure that the driver entries without devices have no ->dev */
155 for (i = 0; i < n_ents; i++) {
156 const struct driver_info *entry = info + i;
157 struct udevice *dev;
158
159 if (found[i]) {
160 /* Make sure we can find it */
161 ut_assertnonnull(entry->dev);
162 ut_assertok(device_get_by_driver_info(entry, &dev));
163 ut_asserteq_ptr(dev, entry->dev);
164 } else {
165 ut_assertnull(entry->dev);
166 ut_asserteq(-ENOENT,
167 device_get_by_driver_info(entry, &dev));
168 }
169 }
170
171 return 0;
172}
173DM_TEST(dm_test_of_platdata_dev, UT_TESTF_SCAN_PDATA);
Simon Glass88280522020-10-03 11:31:32 -0600174
175/* Test handling of phandles that point to other devices */
176static int dm_test_of_platdata_phandle(struct unit_test_state *uts)
177{
178 struct dtd_sandbox_clk_test *plat;
179 struct udevice *dev, *clk;
180
181 ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
182 ut_asserteq_str("sandbox_clk_test", dev->name);
183 plat = dev_get_platdata(dev);
184
185 ut_assertok(device_get_by_driver_info(plat->clocks[0].node, &clk));
186 ut_asserteq_str("fixed_clock", clk->name);
187
188 ut_assertok(device_get_by_driver_info(plat->clocks[1].node, &clk));
189 ut_asserteq_str("sandbox_clk", clk->name);
190 ut_asserteq(1, plat->clocks[1].arg[0]);
191
192 ut_assertok(device_get_by_driver_info(plat->clocks[2].node, &clk));
193 ut_asserteq_str("sandbox_clk", clk->name);
194 ut_asserteq(0, plat->clocks[2].arg[0]);
195
196 ut_assertok(device_get_by_driver_info(plat->clocks[3].node, &clk));
197 ut_asserteq_str("sandbox_clk", clk->name);
198 ut_asserteq(3, plat->clocks[3].arg[0]);
199
200 ut_assertok(device_get_by_driver_info(plat->clocks[4].node, &clk));
201 ut_asserteq_str("sandbox_clk", clk->name);
202 ut_asserteq(2, plat->clocks[4].arg[0]);
203
204 return 0;
205}
206DM_TEST(dm_test_of_platdata_phandle, UT_TESTF_SCAN_PDATA);