sandbox: Create a new sandbox_noinst build
[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 #include <asm/global_data.h>
10
11 /* Test that we can find a device using of-platdata */
12 static int dm_test_of_plat_base(struct unit_test_state *uts)
13 {
14         struct udevice *dev;
15
16         ut_assertok(uclass_first_device_err(UCLASS_SERIAL, &dev));
17         ut_asserteq_str("sandbox_serial", dev->name);
18
19         return 0;
20 }
21 DM_TEST(dm_test_of_plat_base, UT_TESTF_SCAN_PDATA);
22
23 /* Test that we can read properties from a device */
24 static int dm_test_of_plat_props(struct unit_test_state *uts)
25 {
26         struct dtd_sandbox_spl_test *plat;
27         struct udevice *dev;
28         int i;
29
30         /* Skip the clock */
31         ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
32         ut_asserteq_str("sandbox_clk_test", dev->name);
33
34         ut_assertok(uclass_next_device_err(&dev));
35         plat = dev_get_plat(dev);
36         ut_assert(plat->boolval);
37         ut_asserteq(1, plat->intval);
38         ut_asserteq(4, ARRAY_SIZE(plat->intarray));
39         ut_asserteq(2, plat->intarray[0]);
40         ut_asserteq(3, plat->intarray[1]);
41         ut_asserteq(4, plat->intarray[2]);
42         ut_asserteq(0, plat->intarray[3]);
43         ut_asserteq(5, plat->byteval);
44         ut_asserteq(3, ARRAY_SIZE(plat->bytearray));
45         ut_asserteq(6, plat->bytearray[0]);
46         ut_asserteq(0, plat->bytearray[1]);
47         ut_asserteq(0, plat->bytearray[2]);
48         ut_asserteq(9, ARRAY_SIZE(plat->longbytearray));
49         for (i = 0; i < ARRAY_SIZE(plat->longbytearray); i++)
50                 ut_asserteq(9 + i, plat->longbytearray[i]);
51         ut_asserteq_str("message", plat->stringval);
52         ut_asserteq(3, ARRAY_SIZE(plat->stringarray));
53         ut_asserteq_str("multi-word", plat->stringarray[0]);
54         ut_asserteq_str("message", plat->stringarray[1]);
55         ut_asserteq_str("", plat->stringarray[2]);
56
57         ut_assertok(uclass_next_device_err(&dev));
58         plat = dev_get_plat(dev);
59         ut_assert(!plat->boolval);
60         ut_asserteq(3, plat->intval);
61         ut_asserteq(5, plat->intarray[0]);
62         ut_asserteq(0, plat->intarray[1]);
63         ut_asserteq(0, plat->intarray[2]);
64         ut_asserteq(0, plat->intarray[3]);
65         ut_asserteq(8, plat->byteval);
66         ut_asserteq(3, ARRAY_SIZE(plat->bytearray));
67         ut_asserteq(1, plat->bytearray[0]);
68         ut_asserteq(0x23, plat->bytearray[1]);
69         ut_asserteq(0x34, plat->bytearray[2]);
70         for (i = 0; i < ARRAY_SIZE(plat->longbytearray); i++)
71                 ut_asserteq(i < 4 ? 9 + i : 0, plat->longbytearray[i]);
72         ut_asserteq_str("message2", plat->stringval);
73         ut_asserteq_str("another", plat->stringarray[0]);
74         ut_asserteq_str("multi-word", plat->stringarray[1]);
75         ut_asserteq_str("message", plat->stringarray[2]);
76
77         ut_assertok(uclass_next_device_err(&dev));
78         plat = dev_get_plat(dev);
79         ut_assert(!plat->boolval);
80         ut_asserteq_str("one", plat->stringarray[0]);
81         ut_asserteq_str("", plat->stringarray[1]);
82         ut_asserteq_str("", plat->stringarray[2]);
83
84         ut_assertok(uclass_next_device_err(&dev));
85         plat = dev_get_plat(dev);
86         ut_assert(!plat->boolval);
87         ut_asserteq_str("spl", plat->stringarray[0]);
88
89         ut_asserteq(-ENODEV, uclass_next_device_err(&dev));
90
91         return 0;
92 }
93 DM_TEST(dm_test_of_plat_props, UT_TESTF_SCAN_PDATA);
94
95 /*
96  * find_driver_info - recursively find the driver_info for a device
97  *
98  * This sets found[idx] to true when it finds the driver_info record for a
99  * device, where idx is the index in the driver_info linker list.
100  *
101  * @uts: Test state
102  * @parent: Parent to search
103  * @found: bool array to update
104  * @return 0 if OK, non-zero on error
105  */
106 static int find_driver_info(struct unit_test_state *uts, struct udevice *parent,
107                             bool found[])
108 {
109         struct udevice *dev;
110
111         /* If not the root device, find the entry that caused it to be bound */
112         if (parent->parent) {
113                 const int n_ents =
114                         ll_entry_count(struct driver_info, driver_info);
115                 int idx = -1;
116                 int i;
117
118                 for (i = 0; i < n_ents; i++) {
119                         const struct driver_rt *drt = gd_dm_driver_rt() + i;
120
121                         if (drt->dev == parent) {
122                                 idx = i;
123                                 found[idx] = true;
124                                 break;
125                         }
126                 }
127
128                 ut_assert(idx != -1);
129         }
130
131         device_foreach_child(dev, parent) {
132                 int ret;
133
134                 ret = find_driver_info(uts, dev, found);
135                 if (ret < 0)
136                         return ret;
137         }
138
139         return 0;
140 }
141
142 /* Check that every device is recorded in its driver_info struct */
143 static int dm_test_of_plat_dev(struct unit_test_state *uts)
144 {
145         const int n_ents = ll_entry_count(struct driver_info, driver_info);
146         bool found[n_ents];
147         uint i;
148
149         /* Skip this test if there is no platform data */
150         if (CONFIG_IS_ENABLED(OF_PLATDATA_INST))
151                 return 0;
152
153         /* Record the indexes that are found */
154         memset(found, '\0', sizeof(found));
155         ut_assertok(find_driver_info(uts, gd->dm_root, found));
156
157         /* Make sure that the driver entries without devices have no ->dev */
158         for (i = 0; i < n_ents; i++) {
159                 const struct driver_rt *drt = gd_dm_driver_rt() + i;
160                 struct udevice *dev;
161
162                 if (found[i]) {
163                         /* Make sure we can find it */
164                         ut_assertnonnull(drt->dev);
165                         ut_assertok(device_get_by_ofplat_idx(i, &dev));
166                         ut_asserteq_ptr(dev, drt->dev);
167                 } else {
168                         ut_assertnull(drt->dev);
169                         ut_asserteq(-ENOENT, device_get_by_ofplat_idx(i, &dev));
170                 }
171         }
172
173         return 0;
174 }
175 DM_TEST(dm_test_of_plat_dev, UT_TESTF_SCAN_PDATA);
176
177 /* Test handling of phandles that point to other devices */
178 static int dm_test_of_plat_phandle(struct unit_test_state *uts)
179 {
180         struct dtd_sandbox_clk_test *plat;
181         struct udevice *dev, *clk;
182
183         ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
184         ut_asserteq_str("sandbox_clk_test", dev->name);
185         plat = dev_get_plat(dev);
186
187         ut_assertok(device_get_by_ofplat_idx(plat->clocks[0].idx, &clk));
188         ut_asserteq_str("sandbox_fixed_clock", clk->name);
189
190         ut_assertok(device_get_by_ofplat_idx(plat->clocks[1].idx, &clk));
191         ut_asserteq_str("sandbox_clk", clk->name);
192         ut_asserteq(1, plat->clocks[1].arg[0]);
193
194         ut_assertok(device_get_by_ofplat_idx(plat->clocks[2].idx, &clk));
195         ut_asserteq_str("sandbox_clk", clk->name);
196         ut_asserteq(0, plat->clocks[2].arg[0]);
197
198         ut_assertok(device_get_by_ofplat_idx(plat->clocks[3].idx, &clk));
199         ut_asserteq_str("sandbox_clk", clk->name);
200         ut_asserteq(3, plat->clocks[3].arg[0]);
201
202         ut_assertok(device_get_by_ofplat_idx(plat->clocks[4].idx, &clk));
203         ut_asserteq_str("sandbox_clk", clk->name);
204         ut_asserteq(2, plat->clocks[4].arg[0]);
205
206         return 0;
207 }
208 DM_TEST(dm_test_of_plat_phandle, UT_TESTF_SCAN_PDATA);
209
210 #if CONFIG_IS_ENABLED(OF_PLATDATA_PARENT)
211 /* Test that device parents are correctly set up */
212 static int dm_test_of_plat_parent(struct unit_test_state *uts)
213 {
214         struct udevice *rtc, *i2c;
215
216         ut_assertok(uclass_first_device_err(UCLASS_RTC, &rtc));
217         ut_assertok(uclass_first_device_err(UCLASS_I2C, &i2c));
218         ut_asserteq_ptr(i2c, dev_get_parent(rtc));
219
220         return 0;
221 }
222 DM_TEST(dm_test_of_plat_parent, UT_TESTF_SCAN_PDATA);
223 #endif