1 /* 2 * Copyright (c) 2013 Google, Inc 3 * 4 * (C) Copyright 2012 5 * Pavel Herrmann <morpheus.ibis@gmail.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <errno.h> 12 #include <malloc.h> 13 #include <libfdt.h> 14 #include <dm/device.h> 15 #include <dm/device-internal.h> 16 #include <dm/lists.h> 17 #include <dm/platdata.h> 18 #include <dm/uclass.h> 19 #include <dm/util.h> 20 #include <linux/list.h> 21 22 DECLARE_GLOBAL_DATA_PTR; 23 24 static const struct driver_info root_info = { 25 .name = "root_driver", 26 }; 27 28 struct udevice *dm_root(void) 29 { 30 if (!gd->dm_root) { 31 dm_warn("Virtual root driver does not exist!\n"); 32 return NULL; 33 } 34 35 return gd->dm_root; 36 } 37 38 int dm_init(void) 39 { 40 int ret; 41 42 if (gd->dm_root) { 43 dm_warn("Virtual root driver already exists!\n"); 44 return -EINVAL; 45 } 46 INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST); 47 48 ret = device_bind_by_name(NULL, &root_info, &DM_ROOT_NON_CONST); 49 if (ret) 50 return ret; 51 52 return 0; 53 } 54 55 int dm_scan_platdata(void) 56 { 57 int ret; 58 59 ret = lists_bind_drivers(DM_ROOT_NON_CONST); 60 if (ret == -ENOENT) { 61 dm_warn("Some drivers were not found\n"); 62 ret = 0; 63 } 64 if (ret) 65 return ret; 66 67 return 0; 68 } 69 70 #ifdef CONFIG_OF_CONTROL 71 int dm_scan_fdt(const void *blob) 72 { 73 int offset = 0; 74 int ret = 0, err; 75 int depth = 0; 76 77 do { 78 offset = fdt_next_node(blob, offset, &depth); 79 if (offset > 0 && depth == 1) { 80 err = lists_bind_fdt(gd->dm_root, blob, offset); 81 if (err && !ret) 82 ret = err; 83 } 84 } while (offset > 0); 85 86 if (ret) 87 dm_warn("Some drivers failed to bind\n"); 88 89 return ret; 90 } 91 #endif 92 93 /* This is the root driver - all drivers are children of this */ 94 U_BOOT_DRIVER(root_driver) = { 95 .name = "root_driver", 96 .id = UCLASS_ROOT, 97 }; 98 99 /* This is the root uclass */ 100 UCLASS_DRIVER(root) = { 101 .name = "root", 102 .id = UCLASS_ROOT, 103 }; 104