Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f79e9342 authored by Junjie Wu's avatar Junjie Wu
Browse files

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: default avatarJunjie Wu <junjiew@codeaurora.org>
parent a816595b
Loading
Loading
Loading
Loading
+72 −5
Original line number Diff line number Diff line
@@ -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
@@ -263,11 +330,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,
@@ -281,7 +348,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());