]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/core/root.c
update to 2015.04-rc1
[karo-tx-uboot.git] / drivers / core / root.c
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 <fdtdec.h>
13 #include <malloc.h>
14 #include <libfdt.h>
15 #include <dm/device.h>
16 #include <dm/device-internal.h>
17 #include <dm/lists.h>
18 #include <dm/platdata.h>
19 #include <dm/root.h>
20 #include <dm/uclass.h>
21 #include <dm/util.h>
22 #include <linux/list.h>
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 static const struct driver_info root_info = {
27         .name           = "root_driver",
28 };
29
30 struct udevice *dm_root(void)
31 {
32         if (!gd->dm_root) {
33                 dm_warn("Virtual root driver does not exist!\n");
34                 return NULL;
35         }
36
37         return gd->dm_root;
38 }
39
40 int dm_init(void)
41 {
42         int ret;
43
44         if (gd->dm_root) {
45                 dm_warn("Virtual root driver already exists!\n");
46                 return -EINVAL;
47         }
48         INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
49
50         ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);
51         if (ret)
52                 return ret;
53 #ifdef CONFIG_OF_CONTROL
54         DM_ROOT_NON_CONST->of_offset = 0;
55 #endif
56         ret = device_probe(DM_ROOT_NON_CONST);
57         if (ret)
58                 return ret;
59
60         return 0;
61 }
62
63 int dm_uninit(void)
64 {
65         device_remove(dm_root());
66         device_unbind(dm_root());
67
68         return 0;
69 }
70
71 int dm_scan_platdata(bool pre_reloc_only)
72 {
73         int ret;
74
75         ret = lists_bind_drivers(DM_ROOT_NON_CONST, pre_reloc_only);
76         if (ret == -ENOENT) {
77                 dm_warn("Some drivers were not found\n");
78                 ret = 0;
79         }
80
81         return ret;
82 }
83
84 #ifdef CONFIG_OF_CONTROL
85 int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
86                      bool pre_reloc_only)
87 {
88         int ret = 0, err;
89
90         for (offset = fdt_first_subnode(blob, offset);
91              offset > 0;
92              offset = fdt_next_subnode(blob, offset)) {
93                 if (pre_reloc_only &&
94                     !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL))
95                         continue;
96                 if (!fdtdec_get_is_enabled(blob, offset)) {
97                         dm_dbg("   - ignoring disabled device\n");
98                         continue;
99                 }
100                 err = lists_bind_fdt(parent, blob, offset, NULL);
101                 if (err && !ret)
102                         ret = err;
103         }
104
105         if (ret)
106                 dm_warn("Some drivers failed to bind\n");
107
108         return ret;
109 }
110
111 int dm_scan_fdt(const void *blob, bool pre_reloc_only)
112 {
113         return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only);
114 }
115 #endif
116
117 __weak int dm_scan_other(bool pre_reloc_only)
118 {
119         return 0;
120 }
121
122 int dm_init_and_scan(bool pre_reloc_only)
123 {
124         int ret;
125
126         ret = dm_init();
127         if (ret) {
128                 debug("dm_init() failed: %d\n", ret);
129                 return ret;
130         }
131         ret = dm_scan_platdata(pre_reloc_only);
132         if (ret) {
133                 debug("dm_scan_platdata() failed: %d\n", ret);
134                 return ret;
135         }
136 #ifdef CONFIG_OF_CONTROL
137         ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
138         if (ret) {
139                 debug("dm_scan_fdt() failed: %d\n", ret);
140                 return ret;
141         }
142 #endif
143         ret = dm_scan_other(pre_reloc_only);
144         if (ret)
145                 return ret;
146
147         return 0;
148 }
149
150 /* This is the root driver - all drivers are children of this */
151 U_BOOT_DRIVER(root_driver) = {
152         .name   = "root_driver",
153         .id     = UCLASS_ROOT,
154 };
155
156 /* This is the root uclass */
157 UCLASS_DRIVER(root) = {
158         .name   = "root",
159         .id     = UCLASS_ROOT,
160 };