blob: 1cbb096494d2638a57c1a9d7998cda9685054896 [file] [log] [blame]
Simon Glassdd6ab882014-02-26 15:59:18 -07001/*
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>
Simon Glassdf6bd7d2014-06-11 23:29:48 -060013#include <libfdt.h>
Simon Glassdd6ab882014-02-26 15:59:18 -070014#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
22DECLARE_GLOBAL_DATA_PTR;
23
24static const struct driver_info root_info = {
25 .name = "root_driver",
26};
27
Heiko Schocherb74fcb42014-05-22 12:43:05 +020028struct udevice *dm_root(void)
Simon Glassdd6ab882014-02-26 15:59:18 -070029{
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
38int 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 }
Simon Glass34a1d352014-06-11 23:29:49 -060046 INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
Simon Glassdd6ab882014-02-26 15:59:18 -070047
Simon Glass34a1d352014-06-11 23:29:49 -060048 ret = device_bind_by_name(NULL, &root_info, &DM_ROOT_NON_CONST);
Simon Glassdd6ab882014-02-26 15:59:18 -070049 if (ret)
50 return ret;
51
52 return 0;
53}
54
55int dm_scan_platdata(void)
56{
57 int ret;
58
Simon Glass34a1d352014-06-11 23:29:49 -060059 ret = lists_bind_drivers(DM_ROOT_NON_CONST);
Simon Glassdd6ab882014-02-26 15:59:18 -070060 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
71int 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 */
94U_BOOT_DRIVER(root_driver) = {
95 .name = "root_driver",
96 .id = UCLASS_ROOT,
97};
98
99/* This is the root uclass */
100UCLASS_DRIVER(root) = {
101 .name = "root",
102 .id = UCLASS_ROOT,
103};