Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 83262418 authored by Gavin Shan's avatar Gavin Shan Committed by Rob Herring
Browse files

drivers/of: Return allocated memory from of_fdt_unflatten_tree()



This returns the allocate memory chunk, storing the unflattened device
tree, from of_fdt_unflatten_tree() so that memory chunk can be released
on demand in PowerNV PCI hotplug driver.

Signed-off-by: default avatarGavin Shan <gwshan@linux.vnet.ibm.com>
Acked-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarRob Herring <robh@kernel.org>
parent c4263233
Loading
Loading
Loading
Loading
+22 −11
Original line number Diff line number Diff line
@@ -454,8 +454,11 @@ static int unflatten_dt_nodes(const void *blob,
 * @mynodes: The device_node tree created by the call
 * @dt_alloc: An allocator that provides a virtual address to memory
 * for the resulting tree
 *
 * Returns NULL on failure or the memory chunk containing the unflattened
 * device tree on success.
 */
static void __unflatten_device_tree(const void *blob,
static void *__unflatten_device_tree(const void *blob,
				     struct device_node *dad,
				     struct device_node **mynodes,
				     void *(*dt_alloc)(u64 size, u64 align))
@@ -467,7 +470,7 @@ static void __unflatten_device_tree(const void *blob,

	if (!blob) {
		pr_debug("No device tree pointer\n");
		return;
		return NULL;
	}

	pr_debug("Unflattening device tree:\n");
@@ -477,13 +480,13 @@ static void __unflatten_device_tree(const void *blob,

	if (fdt_check_header(blob)) {
		pr_err("Invalid device tree blob header\n");
		return;
		return NULL;
	}

	/* First pass, scan for size */
	size = unflatten_dt_nodes(blob, NULL, dad, NULL);
	if (size < 0)
		return;
		return NULL;

	size = ALIGN(size, 4);
	pr_debug("  size is %d, allocating...\n", size);
@@ -503,6 +506,7 @@ static void __unflatten_device_tree(const void *blob,
			   be32_to_cpup(mem + size));

	pr_debug(" <- unflatten_device_tree()\n");
	return mem;
}

static void *kernel_tree_alloc(u64 size, u64 align)
@@ -522,14 +526,21 @@ static DEFINE_MUTEX(of_fdt_unflatten_mutex);
 * tree of struct device_node. It also fills the "name" and "type"
 * pointers of the nodes so the normal device-tree walking functions
 * can be used.
 *
 * Returns NULL on failure or the memory chunk containing the unflattened
 * device tree on success.
 */
void of_fdt_unflatten_tree(const unsigned long *blob,
void *of_fdt_unflatten_tree(const unsigned long *blob,
			    struct device_node *dad,
			    struct device_node **mynodes)
{
	void *mem;

	mutex_lock(&of_fdt_unflatten_mutex);
	__unflatten_device_tree(blob, dad, mynodes, &kernel_tree_alloc);
	mem = __unflatten_device_tree(blob, dad, mynodes, &kernel_tree_alloc);
	mutex_unlock(&of_fdt_unflatten_mutex);

	return mem;
}
EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree);

+3 −3
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ extern bool of_fdt_is_big_endian(const void *blob,
				 unsigned long node);
extern int of_fdt_match(const void *blob, unsigned long node,
			const char *const *compat);
extern void of_fdt_unflatten_tree(const unsigned long *blob,
extern void *of_fdt_unflatten_tree(const unsigned long *blob,
				   struct device_node *dad,
				   struct device_node **mynodes);