aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkateswara Rao Mandela <venkat.mandela@ti.com>2016-12-08 17:29:04 -0600
committerDavid Huang <d-huang@ti.com>2017-09-01 13:14:28 -0500
commit4af733b9c3329015c8cda76a9324f8b53b5ce582 (patch)
tree5dfbd796aada94d526edb020137bd62046c19c6c
parent2ae53d8118933b49609250b7dad4f1374807eb2a (diff)
downloadjacinto6evm-4af733b9c3329015c8cda76a9324f8b53b5ce582.tar.gz
arch: arm: omap2: optimize hwmod lookup during init
Instead of searching through the device tree for nodes with "ti,hwmods" property for every hwmod, 1. traverse the tree once and build a list. 2. search in the list for the hwmod. 3. In case the list is empty, fall back to the original search mechanism. This approach saves ~100 ms of initialization time on a DRA7xx processor running at 1 GHz. TODO: Free the allocated list TODO: Check if the list can be allocated even earlier. Change-Id: Ie871a807748a244dd900f228952e994deee70a33 Signed-off-by: Venkateswara Rao Mandela <venkat.mandela@ti.com> [apply to android branch] Signed-off-by: Praneeth Bajjuri <praneeth@ti.com>
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index c8eb5f4acfcb..46bb6c37aa70 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -235,6 +235,14 @@ static unsigned short free_ls, max_ls, ls_supp;
/* inited: set to true once the hwmod code is initialized */
static bool inited;
+static LIST_HEAD(omap_ti_hwmod_list);
+struct oh_np_index_list {
+ struct device_node *np;
+ int index;
+ struct list_head node;
+ const char *name;
+};
+
/* Private functions */
/**
@@ -2347,6 +2355,70 @@ static int of_dev_find_hwmod(struct device_node *np,
return -ENODEV;
}
+static int of_dev_hwmod_list_lookup(const char *oh_name,
+ int *index,
+ struct device_node **found)
+{
+ struct oh_np_index_list *temp_node;
+
+ if (list_empty(&omap_ti_hwmod_list))
+ return 1;
+
+ *found = NULL;
+ *index = 0;
+
+ list_for_each_entry(temp_node, &omap_ti_hwmod_list, node) {
+ if (strcmp(oh_name, temp_node->name) == 0) {
+ *index = temp_node->index;
+ *found = temp_node->np;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+/**
+ * Builds a list of "ti,hwmods" and their indices for use by later
+ * code.
+ *
+ */
+static int __init omap_hwmod_build_ti_hwmod_list(void)
+{
+ struct device_node *bus;
+ struct device_node *np;
+ int count, i, res;
+ const char *p;
+
+ if (!of_have_populated_dt())
+ return 0;
+
+ bus = of_find_node_by_name(NULL, "ocp");
+ if (!bus)
+ return -ENODEV;
+
+ for_each_node_with_property(np, "ti,hwmods") {
+ count = of_property_count_strings(np, "ti,hwmods");
+ if (count < 1)
+ continue;
+ for (i = 0; i < count; i++) {
+ struct oh_np_index_list *item = NULL;
+ res = of_property_read_string_index(np, "ti,hwmods",
+ i, &p);
+ if (res)
+ continue;
+ item = kzalloc(sizeof(*item), GFP_KERNEL);
+ if (!item)
+ return -ENOMEM;
+ item->index = i;
+ item->np = np;
+ item->name = p;
+ list_add(&item->node, &omap_ti_hwmod_list);
+ }
+
+
+ }
+ return 0;
+}
/**
* of_dev_hwmod_lookup - look up needed hwmod from dt blob
* @np: struct device_node *
@@ -2366,6 +2438,11 @@ static int of_dev_hwmod_lookup(struct device_node *np,
struct device_node *np0 = NULL;
int res;
+ res = of_dev_hwmod_list_lookup(oh->name, index,
+ found);
+ if (res <= 0)
+ return res;
+
res = of_dev_find_hwmod(np, oh);
if (res >= 0) {
*found = np;
@@ -2481,6 +2558,7 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
return 0;
}
+
/**
* _init - initialize internal data for the hwmod @oh
* @oh: struct omap_hwmod *
@@ -3387,8 +3465,8 @@ int __init omap_hwmod_setup_one(const char *oh_name)
*/
static int __init omap_hwmod_setup_all(void)
{
+ omap_hwmod_build_ti_hwmod_list();
_ensure_mpu_hwmod_is_setup(NULL);
-
omap_hwmod_for_each(_init, NULL);
omap_hwmod_for_each(_setup, NULL);