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

Commit e80f6cfe authored by Frank Rowand's avatar Frank Rowand Committed by Chintan Pandya
Browse files

of: add early boot allocation of of_find_node_by_phandle() cache



From: Frank Rowand <frank.rowand@sony.com>

The initial implementation of the of_find_node_by_phandle() cache
allocates the cache using kcalloc().  Add an early boot allocation
of the cache so it will be usable during early boot.  Switch over
to the kcalloc() based cache once normal memory allocation
becomes available.

Change-Id: I6acc88175ba9e4e17107d2f8a0cfd819a079f4d2
Signed-off-by: default avatarFrank Rowand <frank.rowand@sony.com>
Patch-mainline: linux-kernel @ 02/15/18, 06:22
[cpandya@codeaurora.org: resolve trivial merge conflicts]
Signed-off-by: default avatarChintan Pandya <cpandya@codeaurora.org>
parent f64054bb
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -20,9 +20,11 @@

#define pr_fmt(fmt)	"OF: " fmt

#include <linux/bootmem.h>
#include <linux/console.h>
#include <linux/ctype.h>
#include <linux/cpu.h>
#include <linux/memblock.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
@@ -239,6 +241,29 @@ static void of_populate_phandle_cache(void)
	raw_spin_unlock_irqrestore(&devtree_lock, flags);
}

void __init of_populate_phandle_cache_early(void)
{
	u32 cache_entries;
	struct device_node *np;
	u32 phandles = 0;
	size_t size;

	for_each_of_allnodes(np)
		if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL)
			phandles++;

	cache_entries = roundup_pow_of_two(phandles);
	phandle_cache_mask = cache_entries - 1;

	size = cache_entries * sizeof(*phandle_cache);
	phandle_cache = memblock_virt_alloc(size, 4);
	memset(phandle_cache, 0, size);

	for_each_of_allnodes(np)
		if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL)
			phandle_cache[np->phandle & phandle_cache_mask] = np;
}

#ifndef CONFIG_MODULES
static int __init of_free_phandle_cache(void)
{
@@ -258,7 +283,15 @@ late_initcall_sync(of_free_phandle_cache);

void __init of_core_init(void)
{
	unsigned long flags;
	struct device_node *np;
	phys_addr_t size;

	raw_spin_lock_irqsave(&devtree_lock, flags);
	size = (phandle_cache_mask + 1) * sizeof(*phandle_cache);
	memblock_free(__pa(phandle_cache), size);
	phandle_cache = NULL;
	raw_spin_unlock_irqrestore(&devtree_lock, flags);

	of_populate_phandle_cache();

+4 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
#include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
#include <asm/page.h>

#include "of_private.h"

/*
 * of_fdt_limit_memory - limit the number of regions in the /memory node
 * @limit: maximum entries
@@ -1269,6 +1271,8 @@ void __init unflatten_device_tree(void)

	/* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
	of_alias_scan(early_init_dt_alloc_memory_arch);

	of_populate_phandle_cache_early();
}

/**
+2 −0
Original line number Diff line number Diff line
@@ -89,6 +89,8 @@ extern void __of_sysfs_remove_bin_file(struct device_node *np,
/* illegal phandle value (set when unresolved) */
#define OF_PHANDLE_ILLEGAL	0xdeadbeef

extern void __init of_populate_phandle_cache_early(void);

/* iterators for transactions, used for overlays */
/* forward iterator */
#define for_each_transaction_entry(_oft, _te) \