blob: 4f3cc159d03e1feb21a12c3dc6cadf2080d1fa6d [file] [log] [blame]
Simon Glass25dc2e92020-10-25 20:38:29 -06001// SPDX-License-Identifier: GPL-2.0+
2
3#include <common.h>
4#include <dm.h>
Simon Glass64401e72020-10-03 11:31:28 -06005#include <dt-structs.h>
Simon Glass25dc2e92020-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 Glass64401e72020-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 Glass6b927b12020-10-03 11:31:32 -060029 /* Skip the clock */
Simon Glass64401e72020-10-03 11:31:28 -060030 ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
Simon Glass6b927b12020-10-03 11:31:32 -060031 ut_asserteq_str("sandbox_clk_test", dev->name);
32
33 ut_assertok(uclass_next_device_err(&dev));
Simon Glass64401e72020-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 Glassd825ea72020-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) {
Simon Glassd825ea72020-10-03 11:31:31 -0600112 const int n_ents =
113 ll_entry_count(struct driver_info, driver_info);
Simon Glassd825ea72020-10-03 11:31:31 -0600114 int idx = -1;
Simon Glasscfd6a002020-10-03 11:31:33 -0600115 int i;
Simon Glassd825ea72020-10-03 11:31:31 -0600116
Simon Glasscfd6a002020-10-03 11:31:33 -0600117 for (i = 0; i < n_ents; i++) {
118 const struct driver_rt *drt = gd_dm_driver_rt() + i;
119
120 if (drt->dev == parent) {
121 idx = i;
Simon Glassd825ea72020-10-03 11:31:31 -0600122 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++) {
Simon Glasscfd6a002020-10-03 11:31:33 -0600156 const struct driver_rt *drt = gd_dm_driver_rt() + i;
Simon Glassd825ea72020-10-03 11:31:31 -0600157 const struct driver_info *entry = info + i;
158 struct udevice *dev;
159
160 if (found[i]) {
161 /* Make sure we can find it */
Simon Glasscfd6a002020-10-03 11:31:33 -0600162 ut_assertnonnull(drt->dev);
Simon Glassd825ea72020-10-03 11:31:31 -0600163 ut_assertok(device_get_by_driver_info(entry, &dev));
Simon Glasscfd6a002020-10-03 11:31:33 -0600164 ut_asserteq_ptr(dev, drt->dev);
Simon Glassd825ea72020-10-03 11:31:31 -0600165 } else {
Simon Glasscfd6a002020-10-03 11:31:33 -0600166 ut_assertnull(drt->dev);
Simon Glassd825ea72020-10-03 11:31:31 -0600167 ut_asserteq(-ENOENT,
168 device_get_by_driver_info(entry, &dev));
169 }
170 }
171
172 return 0;
173}
174DM_TEST(dm_test_of_platdata_dev, UT_TESTF_SCAN_PDATA);
Simon Glass6b927b12020-10-03 11:31:32 -0600175
176/* Test handling of phandles that point to other devices */
177static int dm_test_of_platdata_phandle(struct unit_test_state *uts)
178{
179 struct dtd_sandbox_clk_test *plat;
180 struct udevice *dev, *clk;
181
182 ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
183 ut_asserteq_str("sandbox_clk_test", dev->name);
184 plat = dev_get_platdata(dev);
185
Simon Glass5792f4b2020-10-03 11:31:40 -0600186 ut_assertok(device_get_by_driver_info_idx(plat->clocks[0].idx, &clk));
Simon Glass6b927b12020-10-03 11:31:32 -0600187 ut_asserteq_str("fixed_clock", clk->name);
188
Simon Glass5792f4b2020-10-03 11:31:40 -0600189 ut_assertok(device_get_by_driver_info_idx(plat->clocks[1].idx, &clk));
Simon Glass6b927b12020-10-03 11:31:32 -0600190 ut_asserteq_str("sandbox_clk", clk->name);
191 ut_asserteq(1, plat->clocks[1].arg[0]);
192
Simon Glass5792f4b2020-10-03 11:31:40 -0600193 ut_assertok(device_get_by_driver_info_idx(plat->clocks[2].idx, &clk));
Simon Glass6b927b12020-10-03 11:31:32 -0600194 ut_asserteq_str("sandbox_clk", clk->name);
195 ut_asserteq(0, plat->clocks[2].arg[0]);
196
Simon Glass5792f4b2020-10-03 11:31:40 -0600197 ut_assertok(device_get_by_driver_info_idx(plat->clocks[3].idx, &clk));
Simon Glass6b927b12020-10-03 11:31:32 -0600198 ut_asserteq_str("sandbox_clk", clk->name);
199 ut_asserteq(3, plat->clocks[3].arg[0]);
200
Simon Glass5792f4b2020-10-03 11:31:40 -0600201 ut_assertok(device_get_by_driver_info_idx(plat->clocks[4].idx, &clk));
Simon Glass6b927b12020-10-03 11:31:32 -0600202 ut_asserteq_str("sandbox_clk", clk->name);
203 ut_asserteq(2, plat->clocks[4].arg[0]);
204
205 return 0;
206}
207DM_TEST(dm_test_of_platdata_phandle, UT_TESTF_SCAN_PDATA);
Simon Glass4d4558e2020-10-03 11:31:36 -0600208
209#if CONFIG_IS_ENABLED(OF_PLATDATA_PARENT)
210/* Test that device parents are correctly set up */
211static int dm_test_of_platdata_parent(struct unit_test_state *uts)
212{
213 struct udevice *rtc, *i2c;
214
215 ut_assertok(uclass_first_device_err(UCLASS_RTC, &rtc));
216 ut_assertok(uclass_first_device_err(UCLASS_I2C, &i2c));
217 ut_asserteq_ptr(i2c, dev_get_parent(rtc));
218
219 return 0;
220}
221DM_TEST(dm_test_of_platdata_parent, UT_TESTF_SCAN_PDATA);
222#endif