summaryrefslogtreecommitdiff
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorJunjie Wu <junjiew@codeaurora.org>2014-05-28 16:36:25 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 19:58:51 -0700
commit1bf8600f7c79a5bb8835d3d193399b80ec9df38e (patch)
tree51cfccb15d4241e8c64ee5c5edbf3adfbfa19843 /drivers/cpufreq
parente1d864dc94e8edb63813cc432af9a297e04ac66a (diff)
cpufreq: cpu-boost: Support separate input_boost_freq for different CPUs
Different types of CPUs could have different frequency to satisfy same input workload. Add support for using different input_boost_freq on different CPUs. input_boost_freq now either takes a single number which applies to all CPUs, or cpuid:freq pairs separated by space for different CPUs. Change-Id: I20506a9fbdb4d532d94168bbd61744595bebc8e5 Signed-off-by: Junjie Wu <junjiew@codeaurora.org>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/cpu-boost.c77
1 files changed, 72 insertions, 5 deletions
diff --git a/drivers/cpufreq/cpu-boost.c b/drivers/cpufreq/cpu-boost.c
index 45b38b3a6754..18edb699c1fa 100644
--- a/drivers/cpufreq/cpu-boost.c
+++ b/drivers/cpufreq/cpu-boost.c
@@ -38,6 +38,7 @@ struct cpu_sync {
unsigned int boost_min;
unsigned int input_boost_min;
unsigned int task_load;
+ unsigned int input_boost_freq;
};
static DEFINE_PER_CPU(struct cpu_sync, sync_info);
@@ -51,8 +52,7 @@ module_param(boost_ms, uint, 0644);
static unsigned int sync_threshold;
module_param(sync_threshold, uint, 0644);
-static unsigned int input_boost_freq;
-module_param(input_boost_freq, uint, 0644);
+static bool input_boost_enabled;
static unsigned int input_boost_ms = 40;
module_param(input_boost_ms, uint, 0644);
@@ -66,6 +66,73 @@ module_param(load_based_syncs, bool, 0644);
static u64 last_input_time;
#define MIN_INPUT_INTERVAL (150 * USEC_PER_MSEC)
+static int set_input_boost_freq(const char *buf, const struct kernel_param *kp)
+{
+ int i, ntokens = 0;
+ unsigned int val, cpu;
+ const char *cp = buf;
+ bool enabled = false;
+
+ while ((cp = strpbrk(cp + 1, " :")))
+ ntokens++;
+
+ /* single number: apply to all CPUs */
+ if (!ntokens) {
+ if (sscanf(buf, "%u\n", &val) != 1)
+ return -EINVAL;
+ for_each_possible_cpu(i)
+ per_cpu(sync_info, i).input_boost_freq = val;
+ goto check_enable;
+ }
+
+ /* CPU:value pair */
+ if (!(ntokens % 2))
+ return -EINVAL;
+
+ cp = buf;
+ for (i = 0; i < ntokens; i += 2) {
+ if (sscanf(cp, "%u:%u", &cpu, &val) != 2)
+ return -EINVAL;
+ if (cpu > num_possible_cpus())
+ return -EINVAL;
+
+ per_cpu(sync_info, cpu).input_boost_freq = val;
+ cp = strchr(cp, ' ');
+ cp++;
+ }
+
+check_enable:
+ for_each_possible_cpu(i) {
+ if (per_cpu(sync_info, i).input_boost_freq) {
+ enabled = true;
+ break;
+ }
+ }
+ input_boost_enabled = enabled;
+
+ return 0;
+}
+
+static int get_input_boost_freq(char *buf, const struct kernel_param *kp)
+{
+ int cnt = 0, cpu;
+ struct cpu_sync *s;
+
+ for_each_possible_cpu(cpu) {
+ s = &per_cpu(sync_info, cpu);
+ cnt += snprintf(buf + cnt, PAGE_SIZE - cnt,
+ "%d:%u ", cpu, s->input_boost_freq);
+ }
+ cnt += snprintf(buf + cnt, PAGE_SIZE - cnt, "\n");
+ return cnt;
+}
+
+static const struct kernel_param_ops param_ops_input_boost_freq = {
+ .set = set_input_boost_freq,
+ .get = get_input_boost_freq,
+};
+module_param_cb(input_boost_freq, &param_ops_input_boost_freq, NULL, 0644);
+
/*
* The CPUFREQ_ADJUST notifier is used to override the current policy min to
* make sure policy min >= boost_min. The cpufreq framework then does the job
@@ -252,11 +319,11 @@ static void do_input_boost(struct work_struct *work)
ret = cpufreq_get_policy(&policy, i);
if (ret)
continue;
- if (policy.cur >= input_boost_freq)
+ if (policy.cur >= i_sync_info->input_boost_freq)
continue;
cancel_delayed_work_sync(&i_sync_info->input_boost_rem);
- i_sync_info->input_boost_min = input_boost_freq;
+ i_sync_info->input_boost_min = i_sync_info->input_boost_freq;
cpufreq_update_policy(i);
queue_delayed_work_on(i_sync_info->cpu, cpu_boost_wq,
&i_sync_info->input_boost_rem,
@@ -270,7 +337,7 @@ static void cpuboost_input_event(struct input_handle *handle,
{
u64 now;
- if (!input_boost_freq)
+ if (!input_boost_enabled)
return;
now = ktime_to_us(ktime_get());