blob: a2a77d36bbfa56be933a80c977009efbb00b6a80 [file] [log] [blame]
Simon Glass079ac592020-12-23 08:11:18 -07001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2014 Google, Inc
4 */
5
6#include <common.h>
7#include <dm.h>
8#include <dm/test.h>
Simon Glass401d1c42020-10-30 21:38:53 -06009#include <asm/global_data.h>
Simon Glass079ac592020-12-23 08:11:18 -070010
11/* Records the last testbus device that was removed */
12static struct udevice *testbus_removed;
13
14struct udevice *testbus_get_clear_removed(void)
15{
16 struct udevice *removed = testbus_removed;
17
18 testbus_removed = NULL;
19
20 return removed;
21}
22
23static int testbus_drv_probe(struct udevice *dev)
24{
25 if (!CONFIG_IS_ENABLED(OF_PLATDATA)) {
26 int ret;
27
28 ret = dm_scan_fdt_dev(dev);
29 if (ret)
30 return ret;
31 }
32
33 return 0;
34}
35
36static int testbus_child_post_bind(struct udevice *dev)
37{
38 struct dm_test_parent_plat *plat;
39
40 plat = dev_get_parent_plat(dev);
41 plat->bind_flag = 1;
42 plat->uclass_bind_flag = 2;
43
44 return 0;
45}
46
47static int testbus_child_pre_probe(struct udevice *dev)
48{
49 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
50
51 parent_data->flag += TEST_FLAG_CHILD_PROBED;
52
53 return 0;
54}
55
56static int testbus_child_pre_probe_uclass(struct udevice *dev)
57{
58 struct dm_test_priv *priv = dev_get_priv(dev);
59
60 priv->uclass_flag++;
61
62 return 0;
63}
64
65static int testbus_child_post_probe_uclass(struct udevice *dev)
66{
67 struct dm_test_priv *priv = dev_get_priv(dev);
68
69 priv->uclass_postp++;
70
71 return 0;
72}
73
74static int testbus_child_post_remove(struct udevice *dev)
75{
76 struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
77
78 parent_data->flag += TEST_FLAG_CHILD_REMOVED;
79 testbus_removed = dev;
80
81 return 0;
82}
83
84static const struct udevice_id testbus_ids[] = {
85 { .compatible = "denx,u-boot-test-bus", .data = DM_TEST_TYPE_FIRST },
86 { }
87};
88
Simon Glass074197a2021-02-03 06:01:09 -070089U_BOOT_DRIVER(denx_u_boot_test_bus) = {
Simon Glass079ac592020-12-23 08:11:18 -070090 .name = "testbus_drv",
91 .of_match = testbus_ids,
92 .id = UCLASS_TEST_BUS,
93 .probe = testbus_drv_probe,
94 .child_post_bind = testbus_child_post_bind,
95 .priv_auto = sizeof(struct dm_test_priv),
96 .plat_auto = sizeof(struct dm_test_pdata),
97 .per_child_auto = sizeof(struct dm_test_parent_data),
98 .per_child_plat_auto = sizeof(struct dm_test_parent_plat),
99 .child_pre_probe = testbus_child_pre_probe,
100 .child_post_remove = testbus_child_post_remove,
101};
102
103UCLASS_DRIVER(testbus) = {
104 .name = "testbus",
105 .id = UCLASS_TEST_BUS,
106 .flags = DM_UC_FLAG_SEQ_ALIAS,
107 .child_pre_probe = testbus_child_pre_probe_uclass,
108 .child_post_probe = testbus_child_post_probe_uclass,
109};
110
111static int testfdt_drv_ping(struct udevice *dev, int pingval, int *pingret)
112{
113 const struct dm_test_pdata *pdata = dev_get_plat(dev);
114 struct dm_test_priv *priv = dev_get_priv(dev);
115
116 *pingret = pingval + pdata->ping_add;
117 priv->ping_total += *pingret;
118
119 return 0;
120}
121
122static const struct test_ops test_ops = {
123 .ping = testfdt_drv_ping,
124};
125
126static int testfdt_of_to_plat(struct udevice *dev)
127{
128 struct dm_test_pdata *pdata = dev_get_plat(dev);
129
130 pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
131 "ping-add", -1);
132 pdata->base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev),
133 "ping-expect");
134
135 return 0;
136}
137
138static int testfdt_drv_probe(struct udevice *dev)
139{
140 struct dm_test_priv *priv = dev_get_priv(dev);
141
142 priv->ping_total += DM_TEST_START_TOTAL;
143
144 /*
145 * If this device is on a bus, the uclass_flag will be set before
146 * calling this function. In the meantime the uclass_postp is
147 * initlized to a value -1. These are used respectively by
148 * dm_test_bus_child_pre_probe_uclass() and
149 * dm_test_bus_child_post_probe_uclass().
150 */
151 priv->uclass_total += priv->uclass_flag;
152 priv->uclass_postp = -1;
153
154 return 0;
155}
156
157static const struct udevice_id testfdt_ids[] = {
158 { .compatible = "denx,u-boot-fdt-test", .data = DM_TEST_TYPE_FIRST },
159 { .compatible = "google,another-fdt-test", .data = DM_TEST_TYPE_SECOND },
160 { }
161};
162
Simon Glass074197a2021-02-03 06:01:09 -0700163DM_DRIVER_ALIAS(denx_u_boot_fdt_test, google_another_fdt_test)
164
165U_BOOT_DRIVER(denx_u_boot_fdt_test) = {
Simon Glass079ac592020-12-23 08:11:18 -0700166 .name = "testfdt_drv",
167 .of_match = testfdt_ids,
168 .id = UCLASS_TEST_FDT,
169 .of_to_plat = testfdt_of_to_plat,
170 .probe = testfdt_drv_probe,
171 .ops = &test_ops,
172 .priv_auto = sizeof(struct dm_test_priv),
173 .plat_auto = sizeof(struct dm_test_pdata),
174};
175
176static const struct udevice_id testfdt1_ids[] = {
177 { .compatible = "denx,u-boot-fdt-test1", .data = DM_TEST_TYPE_FIRST },
178 { }
179};
180
181U_BOOT_DRIVER(testfdt1_drv) = {
182 .name = "testfdt1_drv",
183 .of_match = testfdt1_ids,
184 .id = UCLASS_TEST_FDT,
185 .of_to_plat = testfdt_of_to_plat,
186 .probe = testfdt_drv_probe,
187 .ops = &test_ops,
188 .priv_auto = sizeof(struct dm_test_priv),
189 .plat_auto = sizeof(struct dm_test_pdata),
190 .flags = DM_FLAG_PRE_RELOC,
191};
192
193/* From here is the testfdt uclass code */
194int testfdt_ping(struct udevice *dev, int pingval, int *pingret)
195{
196 const struct test_ops *ops = device_get_ops(dev);
197
198 if (!ops->ping)
199 return -ENOSYS;
200
201 return ops->ping(dev, pingval, pingret);
202}
203
204UCLASS_DRIVER(testfdt) = {
205 .name = "testfdt",
206 .id = UCLASS_TEST_FDT,
207 .flags = DM_UC_FLAG_SEQ_ALIAS,
208};
209
210static const struct udevice_id testfdtm_ids[] = {
211 { .compatible = "denx,u-boot-fdtm-test" },
212 { }
213};
214
215U_BOOT_DRIVER(testfdtm_drv) = {
216 .name = "testfdtm_drv",
217 .of_match = testfdtm_ids,
218 .id = UCLASS_TEST_FDT_MANUAL,
219};
220
221UCLASS_DRIVER(testfdtm) = {
222 .name = "testfdtm",
223 .id = UCLASS_TEST_FDT_MANUAL,
224 .flags = DM_UC_FLAG_SEQ_ALIAS | DM_UC_FLAG_NO_AUTO_SEQ,
225};