diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2016-06-10 15:03:36 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-06-14 16:00:16 +1000 |
commit | c6a49d88e2f45ecdd969c7dfebdccc44ffcbf5fc (patch) | |
tree | 45aa35bee3ffcec7eed2161cec050f86723bfbf6 /core/fdt.c | |
parent | 229c79d4903ae6d292354eebef56039f7d8219d6 (diff) | |
download | skiboot-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/fdt.c')
-rw-r--r-- | core/fdt.c | 40 |
1 files changed, 40 insertions, 0 deletions
@@ -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); |