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/root.h> 19 #include <dm/uclass.h> 20 #include <dm/util.h> 21 #include <linux/list.h> 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 static const struct driver_info root_info = { 26 .name = "root_driver", 27 }; 28 29 struct udevice *dm_root(void) 30 { 31 if (!gd->dm_root) { 32 dm_warn("Virtual root driver does not exist!\n"); 33 return NULL; 34 } 35 36 return gd->dm_root; 37 } 38 39 int dm_init(void) 40 { 41 int ret; 42 43 if (gd->dm_root) { 44 dm_warn("Virtual root driver already exists!\n"); 45 return -EINVAL; 46 } 47 INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST); 48 49 ret = device_bind_by_name(NULL, &root_info, &DM_ROOT_NON_CONST); 50 if (ret) 51 return ret; 52 53 return 0; 54 } 55 56 int dm_scan_platdata(void) 57 { 58 int ret; 59 60 ret = lists_bind_drivers(DM_ROOT_NON_CONST); 61 if (ret == -ENOENT) { 62 dm_warn("Some drivers were not found\n"); 63 ret = 0; 64 } 65 if (ret) 66 return ret; 67 68 return 0; 69 } 70 71 #ifdef CONFIG_OF_CONTROL 72 int dm_scan_fdt(const void *blob) 73 { 74 int offset = 0; 75 int ret = 0, err; 76 int depth = 0; 77 78 do { 79 offset = fdt_next_node(blob, offset, &depth); 80 if (offset > 0 && depth == 1) { 81 err = lists_bind_fdt(gd->dm_root, blob, offset); 82 if (err && !ret) 83 ret = err; 84 } 85 } while (offset > 0); 86 87 if (ret) 88 dm_warn("Some drivers failed to bind\n"); 89 90 return ret; 91 } 92 #endif 93 94 /* This is the root driver - all drivers are children of this */ 95 U_BOOT_DRIVER(root_driver) = { 96 .name = "root_driver", 97 .id = UCLASS_ROOT, 98 }; 99 100 /* This is the root uclass */ 101 UCLASS_DRIVER(root) = { 102 .name = "root", 103 .id = UCLASS_ROOT, 104 }; 105