Merge branch 'linux-linaro-lsk' into linux-linaro-lsk-android
[firefly-linux-kernel-4.4.55.git] / drivers / cpufreq / cpufreq_interactive.c
index 66c096dcb1a2b0be66e6d7b865ab715e521be525..e1933678f2d04283f978329ddf66dc662a0c0715 100644 (file)
@@ -30,8 +30,7 @@
 #include <linux/workqueue.h>
 #include <linux/kthread.h>
 #include <linux/slab.h>
-#include <linux/kernel_stat.h>
-#include <asm/cputime.h>
+#include "cpufreq_governor.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/cpufreq_interactive.h>
@@ -119,44 +118,6 @@ struct cpufreq_interactive_tunables *common_tunables;
 
 static struct attribute_group *get_sysfs_attr(void);
 
-static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
-                                                 cputime64_t *wall)
-{
-       u64 idle_time;
-       u64 cur_wall_time;
-       u64 busy_time;
-
-       cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
-
-       busy_time  = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
-       busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
-       busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
-       busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
-       busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
-       busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
-
-       idle_time = cur_wall_time - busy_time;
-       if (wall)
-               *wall = jiffies_to_usecs(cur_wall_time);
-
-       return jiffies_to_usecs(idle_time);
-}
-
-static inline cputime64_t get_cpu_idle_time(
-       unsigned int cpu,
-       cputime64_t *wall,
-       bool io_is_busy)
-{
-       u64 idle_time = get_cpu_idle_time_us(cpu, wall);
-
-       if (idle_time == -1ULL)
-               idle_time = get_cpu_idle_time_jiffy(cpu, wall);
-       else if (!io_is_busy)
-               idle_time += get_cpu_iowait_time_us(cpu, wall);
-
-       return idle_time;
-}
-
 static void cpufreq_interactive_timer_resched(
        struct cpufreq_interactive_cpuinfo *pcpu)
 {
@@ -348,13 +309,13 @@ static u64 update_load(int cpu)
                pcpu->policy->governor_data;
        u64 now;
        u64 now_idle;
-       unsigned int delta_idle;
-       unsigned int delta_time;
+       u64 delta_idle;
+       u64 delta_time;
        u64 active_time;
 
        now_idle = get_cpu_idle_time(cpu, &now, tunables->io_is_busy);
-       delta_idle = (unsigned int)(now_idle - pcpu->time_in_idle);
-       delta_time = (unsigned int)(now - pcpu->time_in_idle_timestamp);
+       delta_idle = (now_idle - pcpu->time_in_idle);
+       delta_time = (now - pcpu->time_in_idle_timestamp);
 
        if (delta_time <= delta_idle)
                active_time = 0;
@@ -752,7 +713,7 @@ static ssize_t show_target_loads(
                ret += sprintf(buf + ret, "%u%s", tunables->target_loads[i],
                               i & 0x1 ? ":" : " ");
 
-       ret += sprintf(buf + --ret, "\n");
+       sprintf(buf + ret - 1, "\n");
        spin_unlock_irqrestore(&tunables->target_loads_lock, flags);
        return ret;
 }
@@ -792,7 +753,7 @@ static ssize_t show_above_hispeed_delay(
                               tunables->above_hispeed_delay[i],
                               i & 0x1 ? ":" : " ");
 
-       ret += sprintf(buf + --ret, "\n");
+       sprintf(buf + ret - 1, "\n");
        spin_unlock_irqrestore(&tunables->above_hispeed_delay_lock, flags);
        return ret;
 }
@@ -1178,13 +1139,6 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
                        return -ENOMEM;
                }
 
-               rc = sysfs_create_group(get_governor_parent_kobj(policy),
-                               get_sysfs_attr());
-               if (rc) {
-                       kfree(tunables);
-                       return rc;
-               }
-
                tunables->usage_count = 1;
                tunables->above_hispeed_delay = default_above_hispeed_delay;
                tunables->nabove_hispeed_delay =
@@ -1200,16 +1154,26 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
                spin_lock_init(&tunables->target_loads_lock);
                spin_lock_init(&tunables->above_hispeed_delay_lock);
 
+               policy->governor_data = tunables;
+               if (!have_governor_per_policy())
+                       common_tunables = tunables;
+
+               rc = sysfs_create_group(get_governor_parent_kobj(policy),
+                               get_sysfs_attr());
+               if (rc) {
+                       kfree(tunables);
+                       policy->governor_data = NULL;
+                       if (!have_governor_per_policy())
+                               common_tunables = NULL;
+                       return rc;
+               }
+
                if (!policy->governor->initialized) {
                        idle_notifier_register(&cpufreq_interactive_idle_nb);
                        cpufreq_register_notifier(&cpufreq_notifier_block,
                                        CPUFREQ_TRANSITION_NOTIFIER);
                }
 
-               policy->governor_data = tunables;
-               if (!have_governor_per_policy())
-                       common_tunables = tunables;
-
                break;
 
        case CPUFREQ_GOV_POLICY_EXIT:
@@ -1247,6 +1211,8 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
                        pcpu->hispeed_validate_time =
                                pcpu->floor_validate_time;
                        down_write(&pcpu->enable_sem);
+                       del_timer_sync(&pcpu->cpu_timer);
+                       del_timer_sync(&pcpu->cpu_slack_timer);
                        cpufreq_interactive_timer_start(tunables, j);
                        pcpu->governor_enabled = 1;
                        up_write(&pcpu->enable_sem);