diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c index 173ed059d95f..27e2f45ccdd5 100644 --- a/drivers/cpufreq/arm_big_little_dt.c +++ b/drivers/cpufreq/arm_big_little_dt.c @@ -19,6 +19,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -29,60 +30,63 @@ #include #include "arm_big_little.h" -static int dt_init_opp_table(struct device *cpu_dev) +/* get cpu node with valid operating-points */ +static struct device_node *get_cpu_node_with_valid_op(int cpu) { - struct device_node *np, *parent; - int count = 0, ret; - - parent = of_find_node_by_path("/cpus"); - if (!parent) { - pr_err("failed to find OF /cpus\n"); - return -ENOENT; - } - - for_each_child_of_node(parent, np) { - if (count++ != cpu_dev->id) - continue; - if (!of_get_property(np, "operating-points", NULL)) { - ret = -ENODATA; - } else { - cpu_dev->of_node = np; - ret = of_init_opp_table(cpu_dev); - } - of_node_put(np); - of_node_put(parent); - - return ret; - } - - return -ENODEV; -} - -static int dt_get_transition_latency(struct device *cpu_dev) -{ - struct device_node *np, *parent; - u32 transition_latency = CPUFREQ_ETERNAL; + struct device_node *np = NULL, *parent; int count = 0; parent = of_find_node_by_path("/cpus"); if (!parent) { - pr_info("Failed to find OF /cpus. Use CPUFREQ_ETERNAL transition latency\n"); - return CPUFREQ_ETERNAL; + pr_err("failed to find OF /cpus\n"); + return NULL; } for_each_child_of_node(parent, np) { - if (count++ != cpu_dev->id) + if (count++ != cpu) continue; + if (!of_get_property(np, "operating-points", NULL)) { + of_node_put(np); + np = NULL; + } - of_property_read_u32(np, "clock-latency", &transition_latency); - of_node_put(np); - of_node_put(parent); - - return transition_latency; + break; } - pr_info("clock-latency isn't found, use CPUFREQ_ETERNAL transition latency\n"); - return CPUFREQ_ETERNAL; + of_node_put(parent); + return np; +} + +static int dt_init_opp_table(struct device *cpu_dev) +{ + struct device_node *np; + int ret; + + np = get_cpu_node_with_valid_op(cpu_dev->id); + if (!np) + return -ENODATA; + + cpu_dev->of_node = np; + ret = of_init_opp_table(cpu_dev); + of_node_put(np); + + return ret; +} + +static int dt_get_transition_latency(struct device *cpu_dev) +{ + struct device_node *np; + u32 transition_latency = CPUFREQ_ETERNAL; + + np = get_cpu_node_with_valid_op(cpu_dev->id); + if (!np) + return CPUFREQ_ETERNAL; + + of_property_read_u32(np, "clock-latency", &transition_latency); + of_node_put(np); + + pr_debug("%s: clock-latency: %d\n", __func__, transition_latency); + return transition_latency; } static struct cpufreq_arm_bL_ops dt_bL_ops = { @@ -93,6 +97,13 @@ static struct cpufreq_arm_bL_ops dt_bL_ops = { static int generic_bL_init(void) { + struct device_node *np; + + np = get_cpu_node_with_valid_op(0); + if (!np) + return -ENODEV; + + of_node_put(np); return bL_cpufreq_register(&dt_bL_ops); } module_init(generic_bL_init);