aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2016-06-10 15:03:36 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-06-14 16:00:16 +1000
commitc6a49d88e2f45ecdd969c7dfebdccc44ffcbf5fc (patch)
tree45aa35bee3ffcec7eed2161cec050f86723bfbf6 /core
parent229c79d4903ae6d292354eebef56039f7d8219d6 (diff)
downloadskiboot-c6a49d88e2f45ecdd969c7dfebdccc44ffcbf5fc.zip
skiboot-c6a49d88e2f45ecdd969c7dfebdccc44ffcbf5fc.tar.gz
skiboot-c6a49d88e2f45ecdd969c7dfebdccc44ffcbf5fc.tar.bz2
core/fdt: Introduce opal_get_device_tree()
This introduces OPAL API opal_get_device_tree() to get the device sub-tree. It's going to be used in PCI hot add path. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r--core/fdt.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/core/fdt.c b/core/fdt.c
index 71149fe..a22a840 100644
--- a/core/fdt.c
+++ b/core/fdt.c
@@ -216,3 +216,43 @@ void *create_dtb(const struct dt_node *root, bool exclusive)
return fdt;
}
+
+static int64_t opal_get_device_tree(uint32_t phandle,
+ uint64_t buf, uint64_t len)
+{
+ struct dt_node *root;
+ void *fdt = (void *)buf;
+ uint32_t old_last_phandle;
+ int64_t totalsize;
+ int ret;
+
+ root = dt_find_by_phandle(dt_root, phandle);
+ if (!root)
+ return OPAL_PARAMETER;
+
+ if (!fdt) {
+ fdt = create_dtb(root, true);
+ if (!fdt)
+ return OPAL_INTERNAL_ERROR;
+ totalsize = fdt_totalsize(fdt);
+ free(fdt);
+ return totalsize;
+ }
+
+ if (!len)
+ return OPAL_PARAMETER;
+
+ fdt_error = 0;
+ old_last_phandle = last_phandle;
+ ret = __create_dtb(fdt, len, root, true);
+ if (ret) {
+ last_phandle = old_last_phandle;
+ if (ret == -FDT_ERR_NOSPACE)
+ return OPAL_NO_MEM;
+
+ return OPAL_EMPTY;
+ }
+
+ return OPAL_SUCCESS;
+}
+opal_call(OPAL_GET_DEVICE_TREE, opal_get_device_tree, 3);