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>
This commit is contained in:
parent
e1d864dc94
commit
1bf8600f7c
1 changed files with 72 additions and 5 deletions
|
@ -38,6 +38,7 @@ struct cpu_sync {
|
||||||
unsigned int boost_min;
|
unsigned int boost_min;
|
||||||
unsigned int input_boost_min;
|
unsigned int input_boost_min;
|
||||||
unsigned int task_load;
|
unsigned int task_load;
|
||||||
|
unsigned int input_boost_freq;
|
||||||
};
|
};
|
||||||
|
|
||||||
static DEFINE_PER_CPU(struct cpu_sync, sync_info);
|
static DEFINE_PER_CPU(struct cpu_sync, sync_info);
|
||||||
|
@ -51,8 +52,7 @@ module_param(boost_ms, uint, 0644);
|
||||||
static unsigned int sync_threshold;
|
static unsigned int sync_threshold;
|
||||||
module_param(sync_threshold, uint, 0644);
|
module_param(sync_threshold, uint, 0644);
|
||||||
|
|
||||||
static unsigned int input_boost_freq;
|
static bool input_boost_enabled;
|
||||||
module_param(input_boost_freq, uint, 0644);
|
|
||||||
|
|
||||||
static unsigned int input_boost_ms = 40;
|
static unsigned int input_boost_ms = 40;
|
||||||
module_param(input_boost_ms, uint, 0644);
|
module_param(input_boost_ms, uint, 0644);
|
||||||
|
@ -66,6 +66,73 @@ module_param(load_based_syncs, bool, 0644);
|
||||||
static u64 last_input_time;
|
static u64 last_input_time;
|
||||||
#define MIN_INPUT_INTERVAL (150 * USEC_PER_MSEC)
|
#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, ¶m_ops_input_boost_freq, NULL, 0644);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The CPUFREQ_ADJUST notifier is used to override the current policy min to
|
* 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
|
* 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);
|
ret = cpufreq_get_policy(&policy, i);
|
||||||
if (ret)
|
if (ret)
|
||||||
continue;
|
continue;
|
||||||
if (policy.cur >= input_boost_freq)
|
if (policy.cur >= i_sync_info->input_boost_freq)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cancel_delayed_work_sync(&i_sync_info->input_boost_rem);
|
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);
|
cpufreq_update_policy(i);
|
||||||
queue_delayed_work_on(i_sync_info->cpu, cpu_boost_wq,
|
queue_delayed_work_on(i_sync_info->cpu, cpu_boost_wq,
|
||||||
&i_sync_info->input_boost_rem,
|
&i_sync_info->input_boost_rem,
|
||||||
|
@ -270,7 +337,7 @@ static void cpuboost_input_event(struct input_handle *handle,
|
||||||
{
|
{
|
||||||
u64 now;
|
u64 now;
|
||||||
|
|
||||||
if (!input_boost_freq)
|
if (!input_boost_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
now = ktime_to_us(ktime_get());
|
now = ktime_to_us(ktime_get());
|
||||||
|
|
Loading…
Add table
Reference in a new issue