root.c 1.8 KB
Newer Older
S
Simon Glass 已提交
1 2 3 4 5 6 7 8 9 10 11 12
/*
 * Copyright (c) 2013 Google, Inc
 *
 * (C) Copyright 2012
 * Pavel Herrmann <morpheus.ibis@gmail.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <errno.h>
#include <malloc.h>
13
#include <libfdt.h>
S
Simon Glass 已提交
14 15 16 17
#include <dm/device.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/platdata.h>
J
Jeroen Hofstee 已提交
18
#include <dm/root.h>
S
Simon Glass 已提交
19 20 21 22 23 24 25 26 27 28
#include <dm/uclass.h>
#include <dm/util.h>
#include <linux/list.h>

DECLARE_GLOBAL_DATA_PTR;

static const struct driver_info root_info = {
	.name		= "root_driver",
};

29
struct udevice *dm_root(void)
S
Simon Glass 已提交
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
{
	if (!gd->dm_root) {
		dm_warn("Virtual root driver does not exist!\n");
		return NULL;
	}

	return gd->dm_root;
}

int dm_init(void)
{
	int ret;

	if (gd->dm_root) {
		dm_warn("Virtual root driver already exists!\n");
		return -EINVAL;
	}
47
	INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
S
Simon Glass 已提交
48

49
	ret = device_bind_by_name(NULL, &root_info, &DM_ROOT_NON_CONST);
50 51 52
	if (ret)
		return ret;
	ret = device_probe(DM_ROOT_NON_CONST);
S
Simon Glass 已提交
53 54 55 56 57 58 59 60 61 62
	if (ret)
		return ret;

	return 0;
}

int dm_scan_platdata(void)
{
	int ret;

63
	ret = lists_bind_drivers(DM_ROOT_NON_CONST);
S
Simon Glass 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
	if (ret == -ENOENT) {
		dm_warn("Some drivers were not found\n");
		ret = 0;
	}
	if (ret)
		return ret;

	return 0;
}

#ifdef CONFIG_OF_CONTROL
int dm_scan_fdt(const void *blob)
{
	int offset = 0;
	int ret = 0, err;
	int depth = 0;

	do {
		offset = fdt_next_node(blob, offset, &depth);
		if (offset > 0 && depth == 1) {
			err = lists_bind_fdt(gd->dm_root, blob, offset);
			if (err && !ret)
				ret = err;
		}
	} while (offset > 0);

	if (ret)
		dm_warn("Some drivers failed to bind\n");

	return ret;
}
#endif

/* This is the root driver - all drivers are children of this */
U_BOOT_DRIVER(root_driver) = {
	.name	= "root_driver",
	.id	= UCLASS_ROOT,
};

/* This is the root uclass */
UCLASS_DRIVER(root) = {
	.name	= "root",
	.id	= UCLASS_ROOT,
};