usb: dwc3: add functions to set force mode
[firefly-linux-kernel-4.4.55.git] / drivers / cpufreq / cpufreq_conservative.c
index 0ceb2eff5a7e7044adfcf37a5522b131017d6088..1fa1deb6e91fcbb25b01f8c8e0c23438a0e2bcb4 100644 (file)
  * published by the Free Software Foundation.
  */
 
-#include <linux/cpufreq.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/kernel_stat.h>
-#include <linux/kobject.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/notifier.h>
-#include <linux/percpu-defs.h>
 #include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/types.h>
-
 #include "cpufreq_governor.h"
 
 /* Conservative governor macros */
 
 static DEFINE_PER_CPU(struct cs_cpu_dbs_info_s, cs_cpu_dbs_info);
 
+static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy,
+                                  unsigned int event);
+
+#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
+static
+#endif
+struct cpufreq_governor cpufreq_gov_conservative = {
+       .name                   = "conservative",
+       .governor               = cs_cpufreq_governor_dbs,
+       .max_transition_latency = TRANSITION_LATENCY_LIMIT,
+       .owner                  = THIS_MODULE,
+};
+
 static inline unsigned int get_freq_target(struct cs_dbs_tuners *cs_tuners,
                                           struct cpufreq_policy *policy)
 {
@@ -59,7 +60,7 @@ static inline unsigned int get_freq_target(struct cs_dbs_tuners *cs_tuners,
 static void cs_check_cpu(int cpu, unsigned int load)
 {
        struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, cpu);
-       struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;
+       struct cpufreq_policy *policy = dbs_info->cdbs.shared->policy;
        struct dbs_data *dbs_data = policy->governor_data;
        struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
 
@@ -79,6 +80,7 @@ static void cs_check_cpu(int cpu, unsigned int load)
                        return;
 
                dbs_info->requested_freq += get_freq_target(cs_tuners, policy);
+
                if (dbs_info->requested_freq > policy->max)
                        dbs_info->requested_freq = policy->max;
 
@@ -94,14 +96,17 @@ static void cs_check_cpu(int cpu, unsigned int load)
 
        /* Check for frequency decrease */
        if (load < cs_tuners->down_threshold) {
+               unsigned int freq_target;
                /*
                 * if we cannot reduce the frequency anymore, break out early
                 */
                if (policy->cur == policy->min)
                        return;
 
-               dbs_info->requested_freq -= get_freq_target(cs_tuners, policy);
-               if (dbs_info->requested_freq < policy->min)
+               freq_target = get_freq_target(cs_tuners, policy);
+               if (dbs_info->requested_freq > freq_target)
+                       dbs_info->requested_freq -= freq_target;
+               else
                        dbs_info->requested_freq = policy->min;
 
                __cpufreq_driver_target(policy, dbs_info->requested_freq,
@@ -110,26 +115,15 @@ static void cs_check_cpu(int cpu, unsigned int load)
        }
 }
 
-static void cs_dbs_timer(struct work_struct *work)
+static unsigned int cs_dbs_timer(struct cpu_dbs_info *cdbs,
+                                struct dbs_data *dbs_data, bool modify_all)
 {
-       struct cs_cpu_dbs_info_s *dbs_info = container_of(work,
-                       struct cs_cpu_dbs_info_s, cdbs.work.work);
-       unsigned int cpu = dbs_info->cdbs.cur_policy->cpu;
-       struct cs_cpu_dbs_info_s *core_dbs_info = &per_cpu(cs_cpu_dbs_info,
-                       cpu);
-       struct dbs_data *dbs_data = dbs_info->cdbs.cur_policy->governor_data;
        struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
-       int delay = delay_for_sampling_rate(cs_tuners->sampling_rate);
-       bool modify_all = true;
 
-       mutex_lock(&core_dbs_info->cdbs.timer_mutex);
-       if (!need_load_eval(&core_dbs_info->cdbs, cs_tuners->sampling_rate))
-               modify_all = false;
-       else
-               dbs_check_cpu(dbs_data, cpu);
+       if (modify_all)
+               dbs_check_cpu(dbs_data, cdbs->shared->policy->cpu);
 
-       gov_queue_work(dbs_data, dbs_info->cdbs.cur_policy, delay, modify_all);
-       mutex_unlock(&core_dbs_info->cdbs.timer_mutex);
+       return delay_for_sampling_rate(cs_tuners->sampling_rate);
 }
 
 static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
@@ -138,12 +132,14 @@ static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
        struct cpufreq_freqs *freq = data;
        struct cs_cpu_dbs_info_s *dbs_info =
                                        &per_cpu(cs_cpu_dbs_info, freq->cpu);
-       struct cpufreq_policy *policy;
+       struct cpufreq_policy *policy = cpufreq_cpu_get_raw(freq->cpu);
 
-       if (!dbs_info->enable)
+       if (!policy)
                return 0;
 
-       policy = dbs_info->cdbs.cur_policy;
+       /* policy isn't governed by conservative governor */
+       if (policy->governor != &cpufreq_gov_conservative)
+               return 0;
 
        /*
         * we only care if our internally tracked freq moves outside the 'valid'
@@ -156,6 +152,10 @@ static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
        return 0;
 }
 
+static struct notifier_block cs_cpufreq_notifier_block = {
+       .notifier_call = dbs_cpufreq_notifier,
+};
+
 /************************** sysfs interface ************************/
 static struct common_dbs_data cs_dbs_cdata;
 
@@ -221,8 +221,8 @@ static ssize_t store_down_threshold(struct dbs_data *dbs_data, const char *buf,
        return count;
 }
 
-static ssize_t store_ignore_nice(struct dbs_data *dbs_data, const char *buf,
-               size_t count)
+static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data,
+               const char *buf, size_t count)
 {
        struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
        unsigned int input, j;
@@ -235,10 +235,10 @@ static ssize_t store_ignore_nice(struct dbs_data *dbs_data, const char *buf,
        if (input > 1)
                input = 1;
 
-       if (input == cs_tuners->ignore_nice) /* nothing to do */
+       if (input == cs_tuners->ignore_nice_load) /* nothing to do */
                return count;
 
-       cs_tuners->ignore_nice = input;
+       cs_tuners->ignore_nice_load = input;
 
        /* we need to re-evaluate prev_cpu_idle */
        for_each_online_cpu(j) {
@@ -246,7 +246,7 @@ static ssize_t store_ignore_nice(struct dbs_data *dbs_data, const char *buf,
                dbs_info = &per_cpu(cs_cpu_dbs_info, j);
                dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j,
                                        &dbs_info->cdbs.prev_cpu_wall, 0);
-               if (cs_tuners->ignore_nice)
+               if (cs_tuners->ignore_nice_load)
                        dbs_info->cdbs.prev_cpu_nice =
                                kcpustat_cpu(j).cpustat[CPUTIME_NICE];
        }
@@ -279,7 +279,7 @@ show_store_one(cs, sampling_rate);
 show_store_one(cs, sampling_down_factor);
 show_store_one(cs, up_threshold);
 show_store_one(cs, down_threshold);
-show_store_one(cs, ignore_nice);
+show_store_one(cs, ignore_nice_load);
 show_store_one(cs, freq_step);
 declare_show_sampling_rate_min(cs);
 
@@ -287,7 +287,7 @@ gov_sys_pol_attr_rw(sampling_rate);
 gov_sys_pol_attr_rw(sampling_down_factor);
 gov_sys_pol_attr_rw(up_threshold);
 gov_sys_pol_attr_rw(down_threshold);
-gov_sys_pol_attr_rw(ignore_nice);
+gov_sys_pol_attr_rw(ignore_nice_load);
 gov_sys_pol_attr_rw(freq_step);
 gov_sys_pol_attr_ro(sampling_rate_min);
 
@@ -297,7 +297,7 @@ static struct attribute *dbs_attributes_gov_sys[] = {
        &sampling_down_factor_gov_sys.attr,
        &up_threshold_gov_sys.attr,
        &down_threshold_gov_sys.attr,
-       &ignore_nice_gov_sys.attr,
+       &ignore_nice_load_gov_sys.attr,
        &freq_step_gov_sys.attr,
        NULL
 };
@@ -313,7 +313,7 @@ static struct attribute *dbs_attributes_gov_pol[] = {
        &sampling_down_factor_gov_pol.attr,
        &up_threshold_gov_pol.attr,
        &down_threshold_gov_pol.attr,
-       &ignore_nice_gov_pol.attr,
+       &ignore_nice_load_gov_pol.attr,
        &freq_step_gov_pol.attr,
        NULL
 };
@@ -325,11 +325,11 @@ static struct attribute_group cs_attr_group_gov_pol = {
 
 /************************** sysfs end ************************/
 
-static int cs_init(struct dbs_data *dbs_data)
+static int cs_init(struct dbs_data *dbs_data, bool notify)
 {
        struct cs_dbs_tuners *tuners;
 
-       tuners = kzalloc(sizeof(struct cs_dbs_tuners), GFP_KERNEL);
+       tuners = kzalloc(sizeof(*tuners), GFP_KERNEL);
        if (!tuners) {
                pr_err("%s: kzalloc failed\n", __func__);
                return -ENOMEM;
@@ -338,31 +338,31 @@ static int cs_init(struct dbs_data *dbs_data)
        tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD;
        tuners->down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD;
        tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;
-       tuners->ignore_nice = 0;
+       tuners->ignore_nice_load = 0;
        tuners->freq_step = DEF_FREQUENCY_STEP;
 
        dbs_data->tuners = tuners;
        dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO *
                jiffies_to_usecs(10);
-       mutex_init(&dbs_data->mutex);
+
+       if (notify)
+               cpufreq_register_notifier(&cs_cpufreq_notifier_block,
+                                         CPUFREQ_TRANSITION_NOTIFIER);
+
        return 0;
 }
 
-static void cs_exit(struct dbs_data *dbs_data)
+static void cs_exit(struct dbs_data *dbs_data, bool notify)
 {
+       if (notify)
+               cpufreq_unregister_notifier(&cs_cpufreq_notifier_block,
+                                           CPUFREQ_TRANSITION_NOTIFIER);
+
        kfree(dbs_data->tuners);
 }
 
 define_get_cpu_dbs_routines(cs_cpu_dbs_info);
 
-static struct notifier_block cs_cpufreq_notifier_block = {
-       .notifier_call = dbs_cpufreq_notifier,
-};
-
-static struct cs_ops cs_ops = {
-       .notifier_block = &cs_cpufreq_notifier_block,
-};
-
 static struct common_dbs_data cs_dbs_cdata = {
        .governor = GOV_CONSERVATIVE,
        .attr_group_gov_sys = &cs_attr_group_gov_sys,
@@ -371,9 +371,9 @@ static struct common_dbs_data cs_dbs_cdata = {
        .get_cpu_dbs_info_s = get_cpu_dbs_info_s,
        .gov_dbs_timer = cs_dbs_timer,
        .gov_check_cpu = cs_check_cpu,
-       .gov_ops = &cs_ops,
        .init = cs_init,
        .exit = cs_exit,
+       .mutex = __MUTEX_INITIALIZER(cs_dbs_cdata.mutex),
 };
 
 static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy,
@@ -382,16 +382,6 @@ static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy,
        return cpufreq_governor_dbs(policy, &cs_dbs_cdata, event);
 }
 
-#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
-static
-#endif
-struct cpufreq_governor cpufreq_gov_conservative = {
-       .name                   = "conservative",
-       .governor               = cs_cpufreq_governor_dbs,
-       .max_transition_latency = TRANSITION_LATENCY_LIMIT,
-       .owner                  = THIS_MODULE,
-};
-
 static int __init cpufreq_gov_dbs_init(void)
 {
        return cpufreq_register_governor(&cpufreq_gov_conservative);