Merge tag 'memblock-v5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt...
[linux-2.6-microblaze.git] / drivers / thermal / cpufreq_cooling.c
index 612f063..10af334 100644 (file)
@@ -76,7 +76,9 @@ struct cpufreq_cooling_device {
        struct em_perf_domain *em;
        struct cpufreq_policy *policy;
        struct list_head node;
+#ifndef CONFIG_SMP
        struct time_in_idle *idle_time;
+#endif
        struct freq_qos_request qos_req;
 };
 
@@ -132,14 +134,25 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev,
 }
 
 /**
- * get_load() - get load for a cpu since last updated
- * @cpufreq_cdev:      &struct cpufreq_cooling_device for this cpu
- * @cpu:       cpu number
- * @cpu_idx:   index of the cpu in time_in_idle*
+ * get_load() - get load for a cpu
+ * @cpufreq_cdev: struct cpufreq_cooling_device for the cpu
+ * @cpu: cpu number
+ * @cpu_idx: index of the cpu in time_in_idle array
  *
  * Return: The average load of cpu @cpu in percentage since this
  * function was last called.
  */
+#ifdef CONFIG_SMP
+static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu,
+                   int cpu_idx)
+{
+       unsigned long max = arch_scale_cpu_capacity(cpu);
+       unsigned long util;
+
+       util = sched_cpu_util(cpu, max);
+       return (util * 100) / max;
+}
+#else /* !CONFIG_SMP */
 static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu,
                    int cpu_idx)
 {
@@ -161,6 +174,7 @@ static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu,
 
        return load;
 }
+#endif /* CONFIG_SMP */
 
 /**
  * get_dynamic_power() - calculate the dynamic power
@@ -346,6 +360,36 @@ static inline bool em_is_sane(struct cpufreq_cooling_device *cpufreq_cdev,
 }
 #endif /* CONFIG_THERMAL_GOV_POWER_ALLOCATOR */
 
+#ifdef CONFIG_SMP
+static inline int allocate_idle_time(struct cpufreq_cooling_device *cpufreq_cdev)
+{
+       return 0;
+}
+
+static inline void free_idle_time(struct cpufreq_cooling_device *cpufreq_cdev)
+{
+}
+#else
+static int allocate_idle_time(struct cpufreq_cooling_device *cpufreq_cdev)
+{
+       unsigned int num_cpus = cpumask_weight(cpufreq_cdev->policy->related_cpus);
+
+       cpufreq_cdev->idle_time = kcalloc(num_cpus,
+                                         sizeof(*cpufreq_cdev->idle_time),
+                                         GFP_KERNEL);
+       if (!cpufreq_cdev->idle_time)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static void free_idle_time(struct cpufreq_cooling_device *cpufreq_cdev)
+{
+       kfree(cpufreq_cdev->idle_time);
+       cpufreq_cdev->idle_time = NULL;
+}
+#endif /* CONFIG_SMP */
+
 static unsigned int get_state_freq(struct cpufreq_cooling_device *cpufreq_cdev,
                                   unsigned long state)
 {
@@ -441,7 +485,7 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,
        frequency = get_state_freq(cpufreq_cdev, state);
 
        ret = freq_qos_update_request(&cpufreq_cdev->qos_req, frequency);
-       if (ret > 0) {
+       if (ret >= 0) {
                cpufreq_cdev->cpufreq_state = state;
                cpus = cpufreq_cdev->policy->cpus;
                max_capacity = arch_scale_cpu_capacity(cpumask_first(cpus));
@@ -485,7 +529,7 @@ __cpufreq_cooling_register(struct device_node *np,
        struct thermal_cooling_device *cdev;
        struct cpufreq_cooling_device *cpufreq_cdev;
        char dev_name[THERMAL_NAME_LENGTH];
-       unsigned int i, num_cpus;
+       unsigned int i;
        struct device *dev;
        int ret;
        struct thermal_cooling_device_ops *cooling_ops;
@@ -496,7 +540,6 @@ __cpufreq_cooling_register(struct device_node *np,
                return ERR_PTR(-ENODEV);
        }
 
-
        if (IS_ERR_OR_NULL(policy)) {
                pr_err("%s: cpufreq policy isn't valid: %p\n", __func__, policy);
                return ERR_PTR(-EINVAL);
@@ -514,12 +557,10 @@ __cpufreq_cooling_register(struct device_node *np,
                return ERR_PTR(-ENOMEM);
 
        cpufreq_cdev->policy = policy;
-       num_cpus = cpumask_weight(policy->related_cpus);
-       cpufreq_cdev->idle_time = kcalloc(num_cpus,
-                                        sizeof(*cpufreq_cdev->idle_time),
-                                        GFP_KERNEL);
-       if (!cpufreq_cdev->idle_time) {
-               cdev = ERR_PTR(-ENOMEM);
+
+       ret = allocate_idle_time(cpufreq_cdev);
+       if (ret) {
+               cdev = ERR_PTR(ret);
                goto free_cdev;
        }
 
@@ -579,7 +620,7 @@ remove_qos_req:
 remove_ida:
        ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
 free_idle_time:
-       kfree(cpufreq_cdev->idle_time);
+       free_idle_time(cpufreq_cdev);
 free_cdev:
        kfree(cpufreq_cdev);
        return cdev;
@@ -672,7 +713,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
        thermal_cooling_device_unregister(cdev);
        freq_qos_remove_request(&cpufreq_cdev->qos_req);
        ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
-       kfree(cpufreq_cdev->idle_time);
+       free_idle_time(cpufreq_cdev);
        kfree(cpufreq_cdev);
 }
 EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister);