xref: /rk3399_rockchip-uboot/drivers/core/root.c (revision 0e00a84cdedf7a1949486746225b35984b351eca)
16494d708SSimon Glass /*
26494d708SSimon Glass  * Copyright (c) 2013 Google, Inc
36494d708SSimon Glass  *
46494d708SSimon Glass  * (C) Copyright 2012
56494d708SSimon Glass  * Pavel Herrmann <morpheus.ibis@gmail.com>
66494d708SSimon Glass  *
76494d708SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
86494d708SSimon Glass  */
96494d708SSimon Glass 
106494d708SSimon Glass #include <common.h>
116494d708SSimon Glass #include <errno.h>
1294f7afdfSSimon Glass #include <fdtdec.h>
136494d708SSimon Glass #include <malloc.h>
14*0e00a84cSMasahiro Yamada #include <linux/libfdt.h>
156494d708SSimon Glass #include <dm/device.h>
166494d708SSimon Glass #include <dm/device-internal.h>
176494d708SSimon Glass #include <dm/lists.h>
1819c8205eSSimon Glass #include <dm/of.h>
1919c8205eSSimon Glass #include <dm/of_access.h>
206494d708SSimon Glass #include <dm/platdata.h>
2119c8205eSSimon Glass #include <dm/read.h>
22fd536d81SJeroen Hofstee #include <dm/root.h>
236494d708SSimon Glass #include <dm/uclass.h>
246494d708SSimon Glass #include <dm/util.h>
256494d708SSimon Glass #include <linux/list.h>
266494d708SSimon Glass 
276494d708SSimon Glass DECLARE_GLOBAL_DATA_PTR;
286494d708SSimon Glass 
2966eaea6cSStefan Roese struct root_priv {
3066eaea6cSStefan Roese 	fdt_addr_t translation_offset;	/* optional translation offset */
3166eaea6cSStefan Roese };
3266eaea6cSStefan Roese 
336494d708SSimon Glass static const struct driver_info root_info = {
346494d708SSimon Glass 	.name		= "root_driver",
356494d708SSimon Glass };
366494d708SSimon Glass 
3754c5d08aSHeiko Schocher struct udevice *dm_root(void)
386494d708SSimon Glass {
396494d708SSimon Glass 	if (!gd->dm_root) {
406494d708SSimon Glass 		dm_warn("Virtual root driver does not exist!\n");
416494d708SSimon Glass 		return NULL;
426494d708SSimon Glass 	}
436494d708SSimon Glass 
446494d708SSimon Glass 	return gd->dm_root;
456494d708SSimon Glass }
466494d708SSimon Glass 
472f11cd91SSimon Glass void dm_fixup_for_gd_move(struct global_data *new_gd)
482f11cd91SSimon Glass {
492f11cd91SSimon Glass 	/* The sentinel node has moved, so update things that point to it */
50b0d9512aSLokesh Vutla 	if (gd->dm_root) {
512f11cd91SSimon Glass 		new_gd->uclass_root.next->prev = &new_gd->uclass_root;
522f11cd91SSimon Glass 		new_gd->uclass_root.prev->next = &new_gd->uclass_root;
532f11cd91SSimon Glass 	}
54b0d9512aSLokesh Vutla }
552f11cd91SSimon Glass 
5666eaea6cSStefan Roese fdt_addr_t dm_get_translation_offset(void)
5766eaea6cSStefan Roese {
5866eaea6cSStefan Roese 	struct udevice *root = dm_root();
5966eaea6cSStefan Roese 	struct root_priv *priv = dev_get_priv(root);
6066eaea6cSStefan Roese 
6166eaea6cSStefan Roese 	return priv->translation_offset;
6266eaea6cSStefan Roese }
6366eaea6cSStefan Roese 
6466eaea6cSStefan Roese void dm_set_translation_offset(fdt_addr_t offs)
6566eaea6cSStefan Roese {
6666eaea6cSStefan Roese 	struct udevice *root = dm_root();
6766eaea6cSStefan Roese 	struct root_priv *priv = dev_get_priv(root);
6866eaea6cSStefan Roese 
6966eaea6cSStefan Roese 	priv->translation_offset = offs;
7066eaea6cSStefan Roese }
7166eaea6cSStefan Roese 
72484fdf5bSMichal Simek #if defined(CONFIG_NEEDS_MANUAL_RELOC)
73484fdf5bSMichal Simek void fix_drivers(void)
74484fdf5bSMichal Simek {
75484fdf5bSMichal Simek 	struct driver *drv =
76484fdf5bSMichal Simek 		ll_entry_start(struct driver, driver);
77484fdf5bSMichal Simek 	const int n_ents = ll_entry_count(struct driver, driver);
78484fdf5bSMichal Simek 	struct driver *entry;
79484fdf5bSMichal Simek 
80484fdf5bSMichal Simek 	for (entry = drv; entry != drv + n_ents; entry++) {
81484fdf5bSMichal Simek 		if (entry->of_match)
82484fdf5bSMichal Simek 			entry->of_match = (const struct udevice_id *)
83484fdf5bSMichal Simek 				((u32)entry->of_match + gd->reloc_off);
84484fdf5bSMichal Simek 		if (entry->bind)
85484fdf5bSMichal Simek 			entry->bind += gd->reloc_off;
86484fdf5bSMichal Simek 		if (entry->probe)
87484fdf5bSMichal Simek 			entry->probe += gd->reloc_off;
88484fdf5bSMichal Simek 		if (entry->remove)
89484fdf5bSMichal Simek 			entry->remove += gd->reloc_off;
90484fdf5bSMichal Simek 		if (entry->unbind)
91484fdf5bSMichal Simek 			entry->unbind += gd->reloc_off;
92484fdf5bSMichal Simek 		if (entry->ofdata_to_platdata)
93484fdf5bSMichal Simek 			entry->ofdata_to_platdata += gd->reloc_off;
9431e1029aSMichal Simek 		if (entry->child_post_bind)
9531e1029aSMichal Simek 			entry->child_post_bind += gd->reloc_off;
96484fdf5bSMichal Simek 		if (entry->child_pre_probe)
97484fdf5bSMichal Simek 			entry->child_pre_probe += gd->reloc_off;
98484fdf5bSMichal Simek 		if (entry->child_post_remove)
99484fdf5bSMichal Simek 			entry->child_post_remove += gd->reloc_off;
100484fdf5bSMichal Simek 		/* OPS are fixed in every uclass post_probe function */
101484fdf5bSMichal Simek 		if (entry->ops)
102484fdf5bSMichal Simek 			entry->ops += gd->reloc_off;
103484fdf5bSMichal Simek 	}
104484fdf5bSMichal Simek }
105484fdf5bSMichal Simek 
106484fdf5bSMichal Simek void fix_uclass(void)
107484fdf5bSMichal Simek {
108484fdf5bSMichal Simek 	struct uclass_driver *uclass =
109484fdf5bSMichal Simek 		ll_entry_start(struct uclass_driver, uclass);
110484fdf5bSMichal Simek 	const int n_ents = ll_entry_count(struct uclass_driver, uclass);
111484fdf5bSMichal Simek 	struct uclass_driver *entry;
112484fdf5bSMichal Simek 
113484fdf5bSMichal Simek 	for (entry = uclass; entry != uclass + n_ents; entry++) {
114484fdf5bSMichal Simek 		if (entry->post_bind)
115484fdf5bSMichal Simek 			entry->post_bind += gd->reloc_off;
116484fdf5bSMichal Simek 		if (entry->pre_unbind)
117484fdf5bSMichal Simek 			entry->pre_unbind += gd->reloc_off;
11831e1029aSMichal Simek 		if (entry->pre_probe)
11931e1029aSMichal Simek 			entry->pre_probe += gd->reloc_off;
120484fdf5bSMichal Simek 		if (entry->post_probe)
121484fdf5bSMichal Simek 			entry->post_probe += gd->reloc_off;
122484fdf5bSMichal Simek 		if (entry->pre_remove)
123484fdf5bSMichal Simek 			entry->pre_remove += gd->reloc_off;
12431e1029aSMichal Simek 		if (entry->child_post_bind)
12531e1029aSMichal Simek 			entry->child_post_bind += gd->reloc_off;
12631e1029aSMichal Simek 		if (entry->child_pre_probe)
12731e1029aSMichal Simek 			entry->child_pre_probe += gd->reloc_off;
128484fdf5bSMichal Simek 		if (entry->init)
129484fdf5bSMichal Simek 			entry->init += gd->reloc_off;
130484fdf5bSMichal Simek 		if (entry->destroy)
131484fdf5bSMichal Simek 			entry->destroy += gd->reloc_off;
132484fdf5bSMichal Simek 		/* FIXME maybe also need to fix these ops */
133484fdf5bSMichal Simek 		if (entry->ops)
134484fdf5bSMichal Simek 			entry->ops += gd->reloc_off;
135484fdf5bSMichal Simek 	}
136484fdf5bSMichal Simek }
1375aeedebcSAngelo Dureghello 
1385aeedebcSAngelo Dureghello void fix_devices(void)
1395aeedebcSAngelo Dureghello {
1405aeedebcSAngelo Dureghello 	struct driver_info *dev =
1415aeedebcSAngelo Dureghello 		ll_entry_start(struct driver_info, driver_info);
1425aeedebcSAngelo Dureghello 	const int n_ents = ll_entry_count(struct driver_info, driver_info);
1435aeedebcSAngelo Dureghello 	struct driver_info *entry;
1445aeedebcSAngelo Dureghello 
1455aeedebcSAngelo Dureghello 	for (entry = dev; entry != dev + n_ents; entry++) {
1465aeedebcSAngelo Dureghello 		if (entry->platdata)
1475aeedebcSAngelo Dureghello 			entry->platdata += gd->reloc_off;
1485aeedebcSAngelo Dureghello 	}
1495aeedebcSAngelo Dureghello }
1505aeedebcSAngelo Dureghello 
151484fdf5bSMichal Simek #endif
152484fdf5bSMichal Simek 
15319c8205eSSimon Glass int dm_init(bool of_live)
1546494d708SSimon Glass {
1556494d708SSimon Glass 	int ret;
1566494d708SSimon Glass 
1576494d708SSimon Glass 	if (gd->dm_root) {
1586494d708SSimon Glass 		dm_warn("Virtual root driver already exists!\n");
1596494d708SSimon Glass 		return -EINVAL;
1606494d708SSimon Glass 	}
16189876a55SSimon Glass 	INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
1626494d708SSimon Glass 
163484fdf5bSMichal Simek #if defined(CONFIG_NEEDS_MANUAL_RELOC)
164484fdf5bSMichal Simek 	fix_drivers();
165484fdf5bSMichal Simek 	fix_uclass();
1665aeedebcSAngelo Dureghello 	fix_devices();
167484fdf5bSMichal Simek #endif
168484fdf5bSMichal Simek 
16900606d7eSSimon Glass 	ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);
1706494d708SSimon Glass 	if (ret)
1716494d708SSimon Glass 		return ret;
1720f925822SMasahiro Yamada #if CONFIG_IS_ENABLED(OF_CONTROL)
17319c8205eSSimon Glass # if CONFIG_IS_ENABLED(OF_LIVE)
17419c8205eSSimon Glass 	if (of_live)
17519c8205eSSimon Glass 		DM_ROOT_NON_CONST->node = np_to_ofnode(gd->of_root);
17619c8205eSSimon Glass 	else
17719c8205eSSimon Glass #endif
1784984de2bSSimon Glass 		DM_ROOT_NON_CONST->node = offset_to_ofnode(0);
1792f3b95dbSSimon Glass #endif
1807497812dSSimon Glass 	ret = device_probe(DM_ROOT_NON_CONST);
1817497812dSSimon Glass 	if (ret)
1827497812dSSimon Glass 		return ret;
1836494d708SSimon Glass 
1846494d708SSimon Glass 	return 0;
1856494d708SSimon Glass }
1866494d708SSimon Glass 
1879adbd7a1SSimon Glass int dm_uninit(void)
1889adbd7a1SSimon Glass {
189706865afSStefan Roese 	device_remove(dm_root(), DM_REMOVE_NORMAL);
1909adbd7a1SSimon Glass 	device_unbind(dm_root());
1919adbd7a1SSimon Glass 
1929adbd7a1SSimon Glass 	return 0;
1939adbd7a1SSimon Glass }
1949adbd7a1SSimon Glass 
195bc85aa40SStefan Roese #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
196bc85aa40SStefan Roese int dm_remove_devices_flags(uint flags)
197bc85aa40SStefan Roese {
198bc85aa40SStefan Roese 	device_remove(dm_root(), flags);
199bc85aa40SStefan Roese 
200bc85aa40SStefan Roese 	return 0;
201bc85aa40SStefan Roese }
202bc85aa40SStefan Roese #endif
203bc85aa40SStefan Roese 
20400606d7eSSimon Glass int dm_scan_platdata(bool pre_reloc_only)
2056494d708SSimon Glass {
2066494d708SSimon Glass 	int ret;
2076494d708SSimon Glass 
20800606d7eSSimon Glass 	ret = lists_bind_drivers(DM_ROOT_NON_CONST, pre_reloc_only);
2096494d708SSimon Glass 	if (ret == -ENOENT) {
2106494d708SSimon Glass 		dm_warn("Some drivers were not found\n");
2116494d708SSimon Glass 		ret = 0;
2126494d708SSimon Glass 	}
2136494d708SSimon Glass 
214cbf86d71SMasahiro Yamada 	return ret;
2156494d708SSimon Glass }
2166494d708SSimon Glass 
21719c8205eSSimon Glass #if CONFIG_IS_ENABLED(OF_LIVE)
21819c8205eSSimon Glass static int dm_scan_fdt_live(struct udevice *parent,
21919c8205eSSimon Glass 			    const struct device_node *node_parent,
22019c8205eSSimon Glass 			    bool pre_reloc_only)
22119c8205eSSimon Glass {
22219c8205eSSimon Glass 	struct device_node *np;
22319c8205eSSimon Glass 	int ret = 0, err;
22419c8205eSSimon Glass 
22519c8205eSSimon Glass 	for (np = node_parent->child; np; np = np->sibling) {
22619c8205eSSimon Glass 		if (pre_reloc_only &&
22719c8205eSSimon Glass 		    !of_find_property(np, "u-boot,dm-pre-reloc", NULL))
22819c8205eSSimon Glass 			continue;
22919c8205eSSimon Glass 		if (!of_device_is_available(np)) {
230d42197e4SMasahiro Yamada 			pr_debug("   - ignoring disabled device\n");
23119c8205eSSimon Glass 			continue;
23219c8205eSSimon Glass 		}
23319c8205eSSimon Glass 		err = lists_bind_fdt(parent, np_to_ofnode(np), NULL);
23419c8205eSSimon Glass 		if (err && !ret) {
23519c8205eSSimon Glass 			ret = err;
23619c8205eSSimon Glass 			debug("%s: ret=%d\n", np->name, ret);
23719c8205eSSimon Glass 		}
23819c8205eSSimon Glass 	}
23919c8205eSSimon Glass 
24019c8205eSSimon Glass 	if (ret)
24119c8205eSSimon Glass 		dm_warn("Some drivers failed to bind\n");
24219c8205eSSimon Glass 
24319c8205eSSimon Glass 	return ret;
24419c8205eSSimon Glass }
24519c8205eSSimon Glass #endif /* CONFIG_IS_ENABLED(OF_LIVE) */
24619c8205eSSimon Glass 
24729629eb8SSimon Glass #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
248a771a04fSSimon Glass /**
249a771a04fSSimon Glass  * dm_scan_fdt_node() - Scan the device tree and bind drivers for a node
250a771a04fSSimon Glass  *
251a771a04fSSimon Glass  * This scans the subnodes of a device tree node and and creates a driver
252a771a04fSSimon Glass  * for each one.
253a771a04fSSimon Glass  *
254a771a04fSSimon Glass  * @parent: Parent device for the devices that will be created
255a771a04fSSimon Glass  * @blob: Pointer to device tree blob
256a771a04fSSimon Glass  * @offset: Offset of node to scan
257a771a04fSSimon Glass  * @pre_reloc_only: If true, bind only drivers with the DM_FLAG_PRE_RELOC
258a771a04fSSimon Glass  * flag. If false bind all drivers.
259a771a04fSSimon Glass  * @return 0 if OK, -ve on error
260a771a04fSSimon Glass  */
261a771a04fSSimon Glass static int dm_scan_fdt_node(struct udevice *parent, const void *blob,
262a771a04fSSimon Glass 			    int offset, bool pre_reloc_only)
2636494d708SSimon Glass {
2646494d708SSimon Glass 	int ret = 0, err;
2656494d708SSimon Glass 
2661ca7e206SSimon Glass 	for (offset = fdt_first_subnode(blob, offset);
2671ca7e206SSimon Glass 	     offset > 0;
2681ca7e206SSimon Glass 	     offset = fdt_next_subnode(blob, offset)) {
26900606d7eSSimon Glass 		if (pre_reloc_only &&
27027326c7eSHeiko Stübner 		    !dm_fdt_pre_reloc(blob, offset))
27100606d7eSSimon Glass 			continue;
27294f7afdfSSimon Glass 		if (!fdtdec_get_is_enabled(blob, offset)) {
273d42197e4SMasahiro Yamada 			pr_debug("   - ignoring disabled device\n");
27494f7afdfSSimon Glass 			continue;
27594f7afdfSSimon Glass 		}
276f5b5719cSSimon Glass 		err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL);
277bc7b2f43SSimon Glass 		if (err && !ret) {
2786494d708SSimon Glass 			ret = err;
279bc7b2f43SSimon Glass 			debug("%s: ret=%d\n", fdt_get_name(blob, offset, NULL),
280bc7b2f43SSimon Glass 			      ret);
281bc7b2f43SSimon Glass 		}
2826494d708SSimon Glass 	}
2836494d708SSimon Glass 
2846494d708SSimon Glass 	if (ret)
2856494d708SSimon Glass 		dm_warn("Some drivers failed to bind\n");
2866494d708SSimon Glass 
2876494d708SSimon Glass 	return ret;
2886494d708SSimon Glass }
2891ca7e206SSimon Glass 
290cc7f66f7SSimon Glass int dm_scan_fdt_dev(struct udevice *dev)
291cc7f66f7SSimon Glass {
29219c8205eSSimon Glass 	if (!dev_of_valid(dev))
293cc7f66f7SSimon Glass 		return 0;
294cc7f66f7SSimon Glass 
29519c8205eSSimon Glass #if CONFIG_IS_ENABLED(OF_LIVE)
29619c8205eSSimon Glass 	if (of_live_active())
29719c8205eSSimon Glass 		return dm_scan_fdt_live(dev, dev_np(dev),
29819c8205eSSimon Glass 				gd->flags & GD_FLG_RELOC ? false : true);
29919c8205eSSimon Glass 	else
30019c8205eSSimon Glass #endif
301e160f7d4SSimon Glass 	return dm_scan_fdt_node(dev, gd->fdt_blob, dev_of_offset(dev),
302cc7f66f7SSimon Glass 				gd->flags & GD_FLG_RELOC ? false : true);
303cc7f66f7SSimon Glass }
304cc7f66f7SSimon Glass 
3051ca7e206SSimon Glass int dm_scan_fdt(const void *blob, bool pre_reloc_only)
3061ca7e206SSimon Glass {
30719c8205eSSimon Glass #if CONFIG_IS_ENABLED(OF_LIVE)
30819c8205eSSimon Glass 	if (of_live_active())
30919c8205eSSimon Glass 		return dm_scan_fdt_live(gd->dm_root, gd->of_root,
31019c8205eSSimon Glass 					pre_reloc_only);
31119c8205eSSimon Glass 	else
31219c8205eSSimon Glass #endif
3131ca7e206SSimon Glass 	return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only);
3141ca7e206SSimon Glass }
31546fb92f0SPatrice Chotard #else
31646fb92f0SPatrice Chotard static int dm_scan_fdt_node(struct udevice *parent, const void *blob,
31746fb92f0SPatrice Chotard 			    int offset, bool pre_reloc_only)
31846fb92f0SPatrice Chotard {
31946fb92f0SPatrice Chotard 	return 0;
32046fb92f0SPatrice Chotard }
3216494d708SSimon Glass #endif
3226494d708SSimon Glass 
32346fb92f0SPatrice Chotard int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only)
32446fb92f0SPatrice Chotard {
32546fb92f0SPatrice Chotard 	int node, ret;
32646fb92f0SPatrice Chotard 
32746fb92f0SPatrice Chotard 	ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
32846fb92f0SPatrice Chotard 	if (ret) {
32946fb92f0SPatrice Chotard 		debug("dm_scan_fdt() failed: %d\n", ret);
33046fb92f0SPatrice Chotard 		return ret;
33146fb92f0SPatrice Chotard 	}
33246fb92f0SPatrice Chotard 
33346fb92f0SPatrice Chotard 	/* bind fixed-clock */
33446fb92f0SPatrice Chotard 	node = ofnode_to_offset(ofnode_path("/clocks"));
33546fb92f0SPatrice Chotard 	/* if no DT "clocks" node, no need to go further */
33646fb92f0SPatrice Chotard 	if (node < 0)
33746fb92f0SPatrice Chotard 		return ret;
33846fb92f0SPatrice Chotard 
33946fb92f0SPatrice Chotard 	ret = dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node,
34046fb92f0SPatrice Chotard 			       pre_reloc_only);
34146fb92f0SPatrice Chotard 	if (ret)
34246fb92f0SPatrice Chotard 		debug("dm_scan_fdt_node() failed: %d\n", ret);
34346fb92f0SPatrice Chotard 
34446fb92f0SPatrice Chotard 	return ret;
34546fb92f0SPatrice Chotard }
34646fb92f0SPatrice Chotard 
347bb58503dSSimon Glass __weak int dm_scan_other(bool pre_reloc_only)
348bb58503dSSimon Glass {
349bb58503dSSimon Glass 	return 0;
350bb58503dSSimon Glass }
351bb58503dSSimon Glass 
352ab7cd627SSimon Glass int dm_init_and_scan(bool pre_reloc_only)
353ab7cd627SSimon Glass {
354ab7cd627SSimon Glass 	int ret;
355ab7cd627SSimon Glass 
35619c8205eSSimon Glass 	ret = dm_init(IS_ENABLED(CONFIG_OF_LIVE));
357ab7cd627SSimon Glass 	if (ret) {
358ab7cd627SSimon Glass 		debug("dm_init() failed: %d\n", ret);
359ab7cd627SSimon Glass 		return ret;
360ab7cd627SSimon Glass 	}
361ab7cd627SSimon Glass 	ret = dm_scan_platdata(pre_reloc_only);
362ab7cd627SSimon Glass 	if (ret) {
363ab7cd627SSimon Glass 		debug("dm_scan_platdata() failed: %d\n", ret);
364ab7cd627SSimon Glass 		return ret;
365ab7cd627SSimon Glass 	}
366b2b0d3e7SSimon Glass 
36729629eb8SSimon Glass 	if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
36846fb92f0SPatrice Chotard 		ret = dm_extended_scan_fdt(gd->fdt_blob, pre_reloc_only);
369ab7cd627SSimon Glass 		if (ret) {
37046fb92f0SPatrice Chotard 			debug("dm_extended_scan_dt() failed: %d\n", ret);
371ab7cd627SSimon Glass 			return ret;
372ab7cd627SSimon Glass 		}
373b2b0d3e7SSimon Glass 	}
374b2b0d3e7SSimon Glass 
375bb58503dSSimon Glass 	ret = dm_scan_other(pre_reloc_only);
376bb58503dSSimon Glass 	if (ret)
377bb58503dSSimon Glass 		return ret;
378ab7cd627SSimon Glass 
379ab7cd627SSimon Glass 	return 0;
380ab7cd627SSimon Glass }
381ab7cd627SSimon Glass 
3826494d708SSimon Glass /* This is the root driver - all drivers are children of this */
3836494d708SSimon Glass U_BOOT_DRIVER(root_driver) = {
3846494d708SSimon Glass 	.name	= "root_driver",
3856494d708SSimon Glass 	.id	= UCLASS_ROOT,
38666eaea6cSStefan Roese 	.priv_auto_alloc_size = sizeof(struct root_priv),
3876494d708SSimon Glass };
3886494d708SSimon Glass 
3896494d708SSimon Glass /* This is the root uclass */
3906494d708SSimon Glass UCLASS_DRIVER(root) = {
3916494d708SSimon Glass 	.name	= "root",
3926494d708SSimon Glass 	.id	= UCLASS_ROOT,
3936494d708SSimon Glass };
394