Merge branch 'core-objtool-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-block.git] / drivers / base / arch_topology.c
index 6119e11a9f95a9625ab390bb7e7d6d9ab041aab9..e5d691cf824ceaada69942543443fcabf65b8025 100644 (file)
@@ -94,7 +94,7 @@ static void update_topology_flags_workfn(struct work_struct *work)
        update_topology = 0;
 }
 
-static u32 capacity_scale;
+static DEFINE_PER_CPU(u32, freq_factor) = 1;
 static u32 *raw_capacity;
 
 static int free_raw_capacity(void)
@@ -108,17 +108,23 @@ static int free_raw_capacity(void)
 void topology_normalize_cpu_scale(void)
 {
        u64 capacity;
+       u64 capacity_scale;
        int cpu;
 
        if (!raw_capacity)
                return;
 
-       pr_debug("cpu_capacity: capacity_scale=%u\n", capacity_scale);
+       capacity_scale = 1;
        for_each_possible_cpu(cpu) {
-               pr_debug("cpu_capacity: cpu=%d raw_capacity=%u\n",
-                        cpu, raw_capacity[cpu]);
-               capacity = (raw_capacity[cpu] << SCHED_CAPACITY_SHIFT)
-                       / capacity_scale;
+               capacity = raw_capacity[cpu] * per_cpu(freq_factor, cpu);
+               capacity_scale = max(capacity, capacity_scale);
+       }
+
+       pr_debug("cpu_capacity: capacity_scale=%llu\n", capacity_scale);
+       for_each_possible_cpu(cpu) {
+               capacity = raw_capacity[cpu] * per_cpu(freq_factor, cpu);
+               capacity = div64_u64(capacity << SCHED_CAPACITY_SHIFT,
+                       capacity_scale);
                topology_set_cpu_scale(cpu, capacity);
                pr_debug("cpu_capacity: CPU%d cpu_capacity=%lu\n",
                        cpu, topology_get_cpu_scale(cpu));
@@ -127,6 +133,7 @@ void topology_normalize_cpu_scale(void)
 
 bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
 {
+       struct clk *cpu_clk;
        static bool cap_parsing_failed;
        int ret;
        u32 cpu_capacity;
@@ -146,10 +153,22 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
                                return false;
                        }
                }
-               capacity_scale = max(cpu_capacity, capacity_scale);
                raw_capacity[cpu] = cpu_capacity;
                pr_debug("cpu_capacity: %pOF cpu_capacity=%u (raw)\n",
                        cpu_node, raw_capacity[cpu]);
+
+               /*
+                * Update freq_factor for calculating early boot cpu capacities.
+                * For non-clk CPU DVFS mechanism, there's no way to get the
+                * frequency value now, assuming they are running at the same
+                * frequency (by keeping the initial freq_factor value).
+                */
+               cpu_clk = of_clk_get(cpu_node, 0);
+               if (!PTR_ERR_OR_ZERO(cpu_clk)) {
+                       per_cpu(freq_factor, cpu) =
+                               clk_get_rate(cpu_clk) / 1000;
+                       clk_put(cpu_clk);
+               }
        } else {
                if (raw_capacity) {
                        pr_err("cpu_capacity: missing %pOF raw capacity\n",
@@ -188,11 +207,8 @@ init_cpu_capacity_callback(struct notifier_block *nb,
 
        cpumask_andnot(cpus_to_visit, cpus_to_visit, policy->related_cpus);
 
-       for_each_cpu(cpu, policy->related_cpus) {
-               raw_capacity[cpu] = topology_get_cpu_scale(cpu) *
-                                   policy->cpuinfo.max_freq / 1000UL;
-               capacity_scale = max(raw_capacity[cpu], capacity_scale);
-       }
+       for_each_cpu(cpu, policy->related_cpus)
+               per_cpu(freq_factor, cpu) = policy->cpuinfo.max_freq / 1000;
 
        if (cpumask_empty(cpus_to_visit)) {
                topology_normalize_cpu_scale();
@@ -281,7 +297,7 @@ static int __init get_cpu_for_node(struct device_node *node)
 static int __init parse_core(struct device_node *core, int package_id,
                             int core_id)
 {
-       char name[10];
+       char name[20];
        bool leaf = true;
        int i = 0;
        int cpu;
@@ -327,7 +343,7 @@ static int __init parse_core(struct device_node *core, int package_id,
 
 static int __init parse_cluster(struct device_node *cluster, int depth)
 {
-       char name[10];
+       char name[20];
        bool leaf = true;
        bool has_cores = false;
        struct device_node *c;