summaryrefslogtreecommitdiff
path: root/drivers/core/root.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2014-02-26 15:59:18 -0700
committerTom Rini <trini@ti.com>2014-03-04 12:15:29 -0500
commit6494d708bfc630ac0585d5a81707442ebf578eac (patch)
tree09d66a1cd996b9843c644b8029496ddcfcdac1f5 /drivers/core/root.c
parent65c70539e5f1e63921a7fcb86c0ca1f838f96037 (diff)
dm: Add base driver model support
Add driver model functionality for generic board. This includes data structures and base code for registering devices and uclasses (groups of devices with the same purpose, e.g. all I2C ports will be in the same uclass). The feature is enabled with CONFIG_DM. Signed-off-by: Simon Glass <sjg@chromium.org> Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Pavel Herrmann <morpheus.ibis@gmail.com> Signed-off-by: Viktor Křivák <viktor.krivak@gmail.com> Signed-off-by: Tomas Hlavacek <tmshlvck@gmail.com>
Diffstat (limited to 'drivers/core/root.c')
-rw-r--r--drivers/core/root.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/drivers/core/root.c b/drivers/core/root.c
new file mode 100644
index 0000000000..407bc0d046
--- /dev/null
+++ b/drivers/core/root.c
@@ -0,0 +1,102 @@
+/*
+ * 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>
+#include <dm/device.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/platdata.h>
+#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",
+};
+
+struct device *dm_root(void)
+{
+ 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;
+ }
+ INIT_LIST_HEAD(&gd->uclass_root);
+
+ ret = device_bind_by_name(NULL, &root_info, &gd->dm_root);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int dm_scan_platdata(void)
+{
+ int ret;
+
+ ret = lists_bind_drivers(gd->dm_root);
+ 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,
+};