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