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> 140e00a84cSMasahiro 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 && 227930ceb12SJoseph Chen #ifdef CONFIG_USING_KERNEL_DTB 228b455f42cSJoseph Chen (!of_find_property(np, "u-boot,dm-pre-reloc", NULL) && 229930ceb12SJoseph Chen !of_find_property(np, "u-boot,dm-spl", NULL))) 230930ceb12SJoseph Chen #else 23119c8205eSSimon Glass !of_find_property(np, "u-boot,dm-pre-reloc", NULL)) 232930ceb12SJoseph Chen #endif 23319c8205eSSimon Glass continue; 23419c8205eSSimon Glass if (!of_device_is_available(np)) { 235d42197e4SMasahiro Yamada pr_debug(" - ignoring disabled device\n"); 23619c8205eSSimon Glass continue; 23719c8205eSSimon Glass } 23819c8205eSSimon Glass err = lists_bind_fdt(parent, np_to_ofnode(np), NULL); 23919c8205eSSimon Glass if (err && !ret) { 24019c8205eSSimon Glass ret = err; 24119c8205eSSimon Glass debug("%s: ret=%d\n", np->name, ret); 24219c8205eSSimon Glass } 2435120375cSJoseph Chen 244*dfe24df3SJoseph Chen /* There is no compatible in "/firmware", bind it by default. */ 2455120375cSJoseph Chen if (!pre_reloc_only && !strcmp(np->name, "firmware")) 2465120375cSJoseph Chen ret = device_bind_driver_to_node(gd->dm_root, 2475120375cSJoseph Chen "firmware", np->name, np_to_ofnode(np), NULL); 24819c8205eSSimon Glass } 24919c8205eSSimon Glass 25019c8205eSSimon Glass if (ret) 25119c8205eSSimon Glass dm_warn("Some drivers failed to bind\n"); 25219c8205eSSimon Glass 25319c8205eSSimon Glass return ret; 25419c8205eSSimon Glass } 25519c8205eSSimon Glass #endif /* CONFIG_IS_ENABLED(OF_LIVE) */ 25619c8205eSSimon Glass 25729629eb8SSimon Glass #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) 258a771a04fSSimon Glass /** 259a771a04fSSimon Glass * dm_scan_fdt_node() - Scan the device tree and bind drivers for a node 260a771a04fSSimon Glass * 261a771a04fSSimon Glass * This scans the subnodes of a device tree node and and creates a driver 262a771a04fSSimon Glass * for each one. 263a771a04fSSimon Glass * 264a771a04fSSimon Glass * @parent: Parent device for the devices that will be created 265a771a04fSSimon Glass * @blob: Pointer to device tree blob 266a771a04fSSimon Glass * @offset: Offset of node to scan 267a771a04fSSimon Glass * @pre_reloc_only: If true, bind only drivers with the DM_FLAG_PRE_RELOC 268a771a04fSSimon Glass * flag. If false bind all drivers. 269a771a04fSSimon Glass * @return 0 if OK, -ve on error 270a771a04fSSimon Glass */ 271a771a04fSSimon Glass static int dm_scan_fdt_node(struct udevice *parent, const void *blob, 272a771a04fSSimon Glass int offset, bool pre_reloc_only) 2736494d708SSimon Glass { 2746494d708SSimon Glass int ret = 0, err; 275*dfe24df3SJoseph Chen const char *name; 2766494d708SSimon Glass 2771ca7e206SSimon Glass for (offset = fdt_first_subnode(blob, offset); 2781ca7e206SSimon Glass offset > 0; 2791ca7e206SSimon Glass offset = fdt_next_subnode(blob, offset)) { 28000606d7eSSimon Glass if (pre_reloc_only && 28127326c7eSHeiko Stübner !dm_fdt_pre_reloc(blob, offset)) 28200606d7eSSimon Glass continue; 28394f7afdfSSimon Glass if (!fdtdec_get_is_enabled(blob, offset)) { 284d42197e4SMasahiro Yamada pr_debug(" - ignoring disabled device\n"); 28594f7afdfSSimon Glass continue; 28694f7afdfSSimon Glass } 287f5b5719cSSimon Glass err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL); 288bc7b2f43SSimon Glass if (err && !ret) { 2896494d708SSimon Glass ret = err; 290bc7b2f43SSimon Glass debug("%s: ret=%d\n", fdt_get_name(blob, offset, NULL), 291bc7b2f43SSimon Glass ret); 292bc7b2f43SSimon Glass } 293*dfe24df3SJoseph Chen 294*dfe24df3SJoseph Chen /* There is no compatible in "/firmware", bind it by default. */ 295*dfe24df3SJoseph Chen name = fdt_get_name(blob, offset, NULL); 296*dfe24df3SJoseph Chen if (name && !strcmp(name, "firmware")) 297*dfe24df3SJoseph Chen ret = device_bind_driver_to_node(parent, "firmware", 298*dfe24df3SJoseph Chen name, offset_to_ofnode(offset), NULL); 2996494d708SSimon Glass } 3006494d708SSimon Glass 3016494d708SSimon Glass if (ret) 3026494d708SSimon Glass dm_warn("Some drivers failed to bind\n"); 3036494d708SSimon Glass 3046494d708SSimon Glass return ret; 3056494d708SSimon Glass } 3061ca7e206SSimon Glass 307cc7f66f7SSimon Glass int dm_scan_fdt_dev(struct udevice *dev) 308cc7f66f7SSimon Glass { 30919c8205eSSimon Glass if (!dev_of_valid(dev)) 310cc7f66f7SSimon Glass return 0; 311cc7f66f7SSimon Glass 31219c8205eSSimon Glass #if CONFIG_IS_ENABLED(OF_LIVE) 31319c8205eSSimon Glass if (of_live_active()) 31419c8205eSSimon Glass return dm_scan_fdt_live(dev, dev_np(dev), 31519c8205eSSimon Glass gd->flags & GD_FLG_RELOC ? false : true); 31619c8205eSSimon Glass else 31719c8205eSSimon Glass #endif 318e160f7d4SSimon Glass return dm_scan_fdt_node(dev, gd->fdt_blob, dev_of_offset(dev), 319cc7f66f7SSimon Glass gd->flags & GD_FLG_RELOC ? false : true); 320cc7f66f7SSimon Glass } 321cc7f66f7SSimon Glass 3221ca7e206SSimon Glass int dm_scan_fdt(const void *blob, bool pre_reloc_only) 3231ca7e206SSimon Glass { 32419c8205eSSimon Glass #if CONFIG_IS_ENABLED(OF_LIVE) 32519c8205eSSimon Glass if (of_live_active()) 32619c8205eSSimon Glass return dm_scan_fdt_live(gd->dm_root, gd->of_root, 32719c8205eSSimon Glass pre_reloc_only); 32819c8205eSSimon Glass else 32919c8205eSSimon Glass #endif 3301ca7e206SSimon Glass return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only); 3311ca7e206SSimon Glass } 33246fb92f0SPatrice Chotard #else 33346fb92f0SPatrice Chotard static int dm_scan_fdt_node(struct udevice *parent, const void *blob, 33446fb92f0SPatrice Chotard int offset, bool pre_reloc_only) 33546fb92f0SPatrice Chotard { 33646fb92f0SPatrice Chotard return 0; 33746fb92f0SPatrice Chotard } 3386494d708SSimon Glass #endif 3396494d708SSimon Glass 34046fb92f0SPatrice Chotard int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only) 34146fb92f0SPatrice Chotard { 34246fb92f0SPatrice Chotard int node, ret; 34346fb92f0SPatrice Chotard 34446fb92f0SPatrice Chotard ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only); 34546fb92f0SPatrice Chotard if (ret) { 34646fb92f0SPatrice Chotard debug("dm_scan_fdt() failed: %d\n", ret); 34746fb92f0SPatrice Chotard return ret; 34846fb92f0SPatrice Chotard } 34946fb92f0SPatrice Chotard 35046fb92f0SPatrice Chotard /* bind fixed-clock */ 35146fb92f0SPatrice Chotard node = ofnode_to_offset(ofnode_path("/clocks")); 35246fb92f0SPatrice Chotard /* if no DT "clocks" node, no need to go further */ 35346fb92f0SPatrice Chotard if (node < 0) 35446fb92f0SPatrice Chotard return ret; 35546fb92f0SPatrice Chotard 35646fb92f0SPatrice Chotard ret = dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node, 35746fb92f0SPatrice Chotard pre_reloc_only); 35846fb92f0SPatrice Chotard if (ret) 35946fb92f0SPatrice Chotard debug("dm_scan_fdt_node() failed: %d\n", ret); 36046fb92f0SPatrice Chotard 36146fb92f0SPatrice Chotard return ret; 36246fb92f0SPatrice Chotard } 36346fb92f0SPatrice Chotard 364bb58503dSSimon Glass __weak int dm_scan_other(bool pre_reloc_only) 365bb58503dSSimon Glass { 366bb58503dSSimon Glass return 0; 367bb58503dSSimon Glass } 368bb58503dSSimon Glass 369ab7cd627SSimon Glass int dm_init_and_scan(bool pre_reloc_only) 370ab7cd627SSimon Glass { 371ab7cd627SSimon Glass int ret; 372ab7cd627SSimon Glass 37319c8205eSSimon Glass ret = dm_init(IS_ENABLED(CONFIG_OF_LIVE)); 374ab7cd627SSimon Glass if (ret) { 375ab7cd627SSimon Glass debug("dm_init() failed: %d\n", ret); 376ab7cd627SSimon Glass return ret; 377ab7cd627SSimon Glass } 378ab7cd627SSimon Glass ret = dm_scan_platdata(pre_reloc_only); 379ab7cd627SSimon Glass if (ret) { 380ab7cd627SSimon Glass debug("dm_scan_platdata() failed: %d\n", ret); 381ab7cd627SSimon Glass return ret; 382ab7cd627SSimon Glass } 383b2b0d3e7SSimon Glass 38429629eb8SSimon Glass if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { 38546fb92f0SPatrice Chotard ret = dm_extended_scan_fdt(gd->fdt_blob, pre_reloc_only); 386ab7cd627SSimon Glass if (ret) { 38746fb92f0SPatrice Chotard debug("dm_extended_scan_dt() failed: %d\n", ret); 388ab7cd627SSimon Glass return ret; 389ab7cd627SSimon Glass } 390b2b0d3e7SSimon Glass } 391b2b0d3e7SSimon Glass 392bb58503dSSimon Glass ret = dm_scan_other(pre_reloc_only); 393bb58503dSSimon Glass if (ret) 394bb58503dSSimon Glass return ret; 395ab7cd627SSimon Glass 396ab7cd627SSimon Glass return 0; 397ab7cd627SSimon Glass } 398ab7cd627SSimon Glass 3996494d708SSimon Glass /* This is the root driver - all drivers are children of this */ 4006494d708SSimon Glass U_BOOT_DRIVER(root_driver) = { 4016494d708SSimon Glass .name = "root_driver", 4026494d708SSimon Glass .id = UCLASS_ROOT, 40366eaea6cSStefan Roese .priv_auto_alloc_size = sizeof(struct root_priv), 4046494d708SSimon Glass }; 4056494d708SSimon Glass 4066494d708SSimon Glass /* This is the root uclass */ 4076494d708SSimon Glass UCLASS_DRIVER(root) = { 4086494d708SSimon Glass .name = "root", 4096494d708SSimon Glass .id = UCLASS_ROOT, 4106494d708SSimon Glass }; 411