Loading drivers/of/base.c +82 −4 Original line number Diff line number Diff line Loading @@ -197,10 +197,72 @@ int __of_attach_node_sysfs(struct device_node *np) return 0; } static struct device_node **phandle_cache; static u32 phandle_cache_mask; /* * Assumptions behind phandle_cache implementation: * - phandle property values are in a contiguous range of 1..n * * If the assumptions do not hold, then * - the phandle lookup overhead reduction provided by the cache * will likely be less */ static void of_populate_phandle_cache(void) { unsigned long flags; u32 cache_entries; struct device_node *np; u32 phandles = 0; raw_spin_lock_irqsave(&devtree_lock, flags); kfree(phandle_cache); phandle_cache = NULL; 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; phandle_cache = kcalloc(cache_entries, sizeof(*phandle_cache), GFP_ATOMIC); if (!phandle_cache) goto out; for_each_of_allnodes(np) if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL) phandle_cache[np->phandle & phandle_cache_mask] = np; out: raw_spin_unlock_irqrestore(&devtree_lock, flags); } #ifndef CONFIG_MODULES static int __init of_free_phandle_cache(void) { unsigned long flags; raw_spin_lock_irqsave(&devtree_lock, flags); kfree(phandle_cache); phandle_cache = NULL; raw_spin_unlock_irqrestore(&devtree_lock, flags); return 0; } late_initcall_sync(of_free_phandle_cache); #endif void __init of_core_init(void) { struct device_node *np; of_populate_phandle_cache(); /* Create the kset, and register existing nodes */ mutex_lock(&of_mutex); of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj); Loading Loading @@ -1127,16 +1189,32 @@ EXPORT_SYMBOL_GPL(of_modalias_node); */ struct device_node *of_find_node_by_phandle(phandle handle) { struct device_node *np; struct device_node *np = NULL; unsigned long flags; phandle masked_handle; if (!handle) return NULL; raw_spin_lock_irqsave(&devtree_lock, flags); masked_handle = handle & phandle_cache_mask; if (phandle_cache) { if (phandle_cache[masked_handle] && handle == phandle_cache[masked_handle]->phandle) np = phandle_cache[masked_handle]; } if (!np) { for_each_of_allnodes(np) if (np->phandle == handle) if (np->phandle == handle) { if (phandle_cache) phandle_cache[masked_handle] = np; break; } } of_node_get(np); raw_spin_unlock_irqrestore(&devtree_lock, flags); return np; Loading drivers/of/of_private.h +3 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,9 @@ extern void __of_detach_node_sysfs(struct device_node *np); extern void __of_sysfs_remove_bin_file(struct device_node *np, struct property *prop); /* illegal phandle value (set when unresolved) */ #define OF_PHANDLE_ILLEGAL 0xdeadbeef /* iterators for transactions, used for overlays */ /* forward iterator */ #define for_each_transaction_entry(_oft, _te) \ Loading drivers/of/resolver.c +0 −3 Original line number Diff line number Diff line Loading @@ -22,9 +22,6 @@ #include "of_private.h" /* illegal phandle value (set when unresolved) */ #define OF_PHANDLE_ILLEGAL 0xdeadbeef static phandle live_tree_max_phandle(void) { struct device_node *node; Loading Loading
drivers/of/base.c +82 −4 Original line number Diff line number Diff line Loading @@ -197,10 +197,72 @@ int __of_attach_node_sysfs(struct device_node *np) return 0; } static struct device_node **phandle_cache; static u32 phandle_cache_mask; /* * Assumptions behind phandle_cache implementation: * - phandle property values are in a contiguous range of 1..n * * If the assumptions do not hold, then * - the phandle lookup overhead reduction provided by the cache * will likely be less */ static void of_populate_phandle_cache(void) { unsigned long flags; u32 cache_entries; struct device_node *np; u32 phandles = 0; raw_spin_lock_irqsave(&devtree_lock, flags); kfree(phandle_cache); phandle_cache = NULL; 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; phandle_cache = kcalloc(cache_entries, sizeof(*phandle_cache), GFP_ATOMIC); if (!phandle_cache) goto out; for_each_of_allnodes(np) if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL) phandle_cache[np->phandle & phandle_cache_mask] = np; out: raw_spin_unlock_irqrestore(&devtree_lock, flags); } #ifndef CONFIG_MODULES static int __init of_free_phandle_cache(void) { unsigned long flags; raw_spin_lock_irqsave(&devtree_lock, flags); kfree(phandle_cache); phandle_cache = NULL; raw_spin_unlock_irqrestore(&devtree_lock, flags); return 0; } late_initcall_sync(of_free_phandle_cache); #endif void __init of_core_init(void) { struct device_node *np; of_populate_phandle_cache(); /* Create the kset, and register existing nodes */ mutex_lock(&of_mutex); of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj); Loading Loading @@ -1127,16 +1189,32 @@ EXPORT_SYMBOL_GPL(of_modalias_node); */ struct device_node *of_find_node_by_phandle(phandle handle) { struct device_node *np; struct device_node *np = NULL; unsigned long flags; phandle masked_handle; if (!handle) return NULL; raw_spin_lock_irqsave(&devtree_lock, flags); masked_handle = handle & phandle_cache_mask; if (phandle_cache) { if (phandle_cache[masked_handle] && handle == phandle_cache[masked_handle]->phandle) np = phandle_cache[masked_handle]; } if (!np) { for_each_of_allnodes(np) if (np->phandle == handle) if (np->phandle == handle) { if (phandle_cache) phandle_cache[masked_handle] = np; break; } } of_node_get(np); raw_spin_unlock_irqrestore(&devtree_lock, flags); return np; Loading
drivers/of/of_private.h +3 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,9 @@ extern void __of_detach_node_sysfs(struct device_node *np); extern void __of_sysfs_remove_bin_file(struct device_node *np, struct property *prop); /* illegal phandle value (set when unresolved) */ #define OF_PHANDLE_ILLEGAL 0xdeadbeef /* iterators for transactions, used for overlays */ /* forward iterator */ #define for_each_transaction_entry(_oft, _te) \ Loading
drivers/of/resolver.c +0 −3 Original line number Diff line number Diff line Loading @@ -22,9 +22,6 @@ #include "of_private.h" /* illegal phandle value (set when unresolved) */ #define OF_PHANDLE_ILLEGAL 0xdeadbeef static phandle live_tree_max_phandle(void) { struct device_node *node; Loading