dm: treewide: Rename ..._platdata variables to just ..._plat
[pandora-u-boot.git] / test / dm / of_platdata.c
1 // SPDX-License-Identifier: GPL-2.0+
2
3 #include <common.h>
4 #include <dm.h>
5 #include <dt-structs.h>
6 #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 */
11 static int dm_test_of_plat_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 }
20 DM_TEST(dm_test_of_plat_base, UT_TESTF_SCAN_PDATA);
21
22 /* Test that we can read properties from a device */
23 static int dm_test_of_plat_props(struct unit_test_state *uts)
24 {
25         struct dtd_sandbox_spl_test *plat;
26         struct udevice *dev;
27         int i;
28
29         /* Skip the clock */
30         ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
31         ut_asserteq_str("sandbox_clk_test", dev->name);
32
33         ut_assertok(uclass_next_device_err(&dev));
34         plat = dev_get_plat(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_plat(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_plat(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_plat(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 }
92 DM_TEST(dm_test_of_plat_props, UT_TESTF_SCAN_PDATA);
93
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  */
105 static 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 int n_ents =
113                         ll_entry_count(struct driver_info, driver_info);
114                 int idx = -1;
115                 int i;
116
117                 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;
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 */
142 static int dm_test_of_plat_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_rt *drt = gd_dm_driver_rt() + i;
157                 const struct driver_info *entry = info + i;
158                 struct udevice *dev;
159
160                 if (found[i]) {
161                         /* Make sure we can find it */
162                         ut_assertnonnull(drt->dev);
163                         ut_assertok(device_get_by_driver_info(entry, &dev));
164                         ut_asserteq_ptr(dev, drt->dev);
165                 } else {
166                         ut_assertnull(drt->dev);
167                         ut_asserteq(-ENOENT,
168                                     device_get_by_driver_info(entry, &dev));
169                 }
170         }
171
172         return 0;
173 }
174 DM_TEST(dm_test_of_plat_dev, UT_TESTF_SCAN_PDATA);
175
176 /* Test handling of phandles that point to other devices */
177 static int dm_test_of_plat_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_plat(dev);
185
186         ut_assertok(device_get_by_driver_info_idx(plat->clocks[0].idx, &clk));
187         ut_asserteq_str("fixed_clock", clk->name);
188
189         ut_assertok(device_get_by_driver_info_idx(plat->clocks[1].idx, &clk));
190         ut_asserteq_str("sandbox_clk", clk->name);
191         ut_asserteq(1, plat->clocks[1].arg[0]);
192
193         ut_assertok(device_get_by_driver_info_idx(plat->clocks[2].idx, &clk));
194         ut_asserteq_str("sandbox_clk", clk->name);
195         ut_asserteq(0, plat->clocks[2].arg[0]);
196
197         ut_assertok(device_get_by_driver_info_idx(plat->clocks[3].idx, &clk));
198         ut_asserteq_str("sandbox_clk", clk->name);
199         ut_asserteq(3, plat->clocks[3].arg[0]);
200
201         ut_assertok(device_get_by_driver_info_idx(plat->clocks[4].idx, &clk));
202         ut_asserteq_str("sandbox_clk", clk->name);
203         ut_asserteq(2, plat->clocks[4].arg[0]);
204
205         return 0;
206 }
207 DM_TEST(dm_test_of_plat_phandle, UT_TESTF_SCAN_PDATA);
208
209 #if CONFIG_IS_ENABLED(OF_PLATDATA_PARENT)
210 /* Test that device parents are correctly set up */
211 static int dm_test_of_plat_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 }
221 DM_TEST(dm_test_of_plat_parent, UT_TESTF_SCAN_PDATA);
222 #endif