| From 90a80327ee82b46f8eeb7d1dff04f8f04dfc9721 Mon Sep 17 00:00:00 2001 |
| From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> |
| Date: Wed, 21 May 2014 15:31:05 +0200 |
| Subject: ARM: shmobile: Fix device node reference leakage in |
| shmobile_init_delay |
| |
| The of_find_compatible_node() function returns a new reference to the |
| found node. Instead of just adding of_node_put() calls, simplify the |
| code by moving the CPU identification logic inside the loop over cpu |
| nodes, in order to lower complexity from O(n) to O(1) by replacing |
| of_find_compatible_node() calls with of_device_is_compatible(). |
| |
| Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> |
| Acked-by: Magnus Damm <damm+renesas@opensource.se> |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| (cherry picked from commit edc8fb1d6ebdfc4efa009073586d3567c3368475) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| arch/arm/mach-shmobile/timer.c | 50 ++++++++++++++++++++++++------------------ |
| 1 file changed, 29 insertions(+), 21 deletions(-) |
| |
| diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c |
| index 68bc0b82226d..942efdc82a62 100644 |
| --- a/arch/arm/mach-shmobile/timer.c |
| +++ b/arch/arm/mach-shmobile/timer.c |
| @@ -59,29 +59,37 @@ void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz, |
| |
| void __init shmobile_init_delay(void) |
| { |
| - struct device_node *np, *parent; |
| - u32 max_freq, freq; |
| - |
| - max_freq = 0; |
| - |
| - parent = of_find_node_by_path("/cpus"); |
| - if (parent) { |
| - for_each_child_of_node(parent, np) { |
| - if (!of_property_read_u32(np, "clock-frequency", &freq)) |
| - max_freq = max(max_freq, freq); |
| - } |
| - of_node_put(parent); |
| - } |
| + struct device_node *np, *cpus; |
| + bool is_a8_a9 = false; |
| + bool is_a15 = false; |
| + u32 max_freq = 0; |
| + |
| + cpus = of_find_node_by_path("/cpus"); |
| + if (!cpus) |
| + return; |
| + |
| + for_each_child_of_node(cpus, np) { |
| + u32 freq; |
| + |
| + if (!of_property_read_u32(np, "clock-frequency", &freq)) |
| + max_freq = max(max_freq, freq); |
| |
| - if (max_freq) { |
| - if (of_find_compatible_node(NULL, NULL, "arm,cortex-a8")) |
| - shmobile_setup_delay_hz(max_freq, 1, 3); |
| - else if (of_find_compatible_node(NULL, NULL, "arm,cortex-a9")) |
| - shmobile_setup_delay_hz(max_freq, 1, 3); |
| - else if (of_find_compatible_node(NULL, NULL, "arm,cortex-a15")) |
| - if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) |
| - shmobile_setup_delay_hz(max_freq, 2, 4); |
| + if (of_device_is_compatible(np, "arm,cortex-a8") || |
| + of_device_is_compatible(np, "arm,cortex-a9")) |
| + is_a8_a9 = true; |
| + else if (of_device_is_compatible(np, "arm,cortex-a15")) |
| + is_a15 = true; |
| } |
| + |
| + of_node_put(cpus); |
| + |
| + if (!max_freq) |
| + return; |
| + |
| + if (is_a8_a9) |
| + shmobile_setup_delay_hz(max_freq, 1, 3); |
| + else if (is_a15 && !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) |
| + shmobile_setup_delay_hz(max_freq, 2, 4); |
| } |
| |
| static void __init shmobile_late_time_init(void) |
| -- |
| 2.1.2 |
| |