summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Poynor <toddpoynor@google.com>2012-11-28 17:58:17 -0800
committerJohn Stultz <john.stultz@linaro.org>2016-02-16 13:52:46 -0800
commit4727e1aa45b97397fdc32d805f2b40906eddf55d (patch)
tree55f568c9a9e010e66f3af10ef9dd2c3ca60fae5a
parentdc202c38d36161b1b8fe6f1cd49b690ee6d08dcc (diff)
cpufreq: interactive: change speed according to current speed and target load
Add a target_load attribute that specifies how aggressively the governor is to adjust speed to meet the observed load. New target speed is calculated as the current actual speed (may be higher than target speed on SMP) times the CPU load (as a fraction) divided by target load (fraction). cpufreq_frequency_table_target() call use CPUFREQ_RELATION_L to set the next higher speed rather than next lower speed. Change-Id: If432451da82f5fed12e15c9421d7d27792376150 Signed-off-by: Todd Poynor <toddpoynor@google.com>
-rw-r--r--drivers/cpufreq/cpufreq_interactive.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 2b4aad97385c..c4293c5741f7 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -68,6 +68,10 @@ static unsigned int hispeed_freq;
#define DEFAULT_GO_HISPEED_LOAD 85
static unsigned long go_hispeed_load;
+/* Target load. Lower values result in higher CPU speeds. */
+#define DEFAULT_TARGET_LOAD 90
+static unsigned long target_load = DEFAULT_TARGET_LOAD;
+
/*
* The minimum amount of time to spend at a frequency before we can ramp down.
*/
@@ -177,7 +181,7 @@ static void cpufreq_interactive_timer(unsigned long data)
hispeed_freq < pcpu->policy->max) {
new_freq = hispeed_freq;
} else {
- new_freq = pcpu->policy->max * cpu_load / 100;
+ new_freq = pcpu->policy->cur * cpu_load / target_load;
if (new_freq < hispeed_freq)
new_freq = hispeed_freq;
@@ -193,14 +197,14 @@ static void cpufreq_interactive_timer(unsigned long data)
}
}
} else {
- new_freq = hispeed_freq * cpu_load / 100;
+ new_freq = pcpu->policy->cur * cpu_load / target_load;
}
if (new_freq <= hispeed_freq)
pcpu->hispeed_validate_time = now;
if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table,
- new_freq, CPUFREQ_RELATION_H,
+ new_freq, CPUFREQ_RELATION_L,
&index)) {
pr_warn_once("timer %d: cpufreq_frequency_table_target error\n",
(int) data);
@@ -420,6 +424,30 @@ static void cpufreq_interactive_boost(void)
wake_up_process(speedchange_task);
}
+static ssize_t show_target_load(
+ struct kobject *kobj, struct attribute *attr, char *buf)
+{
+ return sprintf(buf, "%lu\n", target_load);
+}
+
+static ssize_t store_target_load(
+ struct kobject *kobj, struct attribute *attr, const char *buf,
+ size_t count)
+{
+ int ret;
+ unsigned long val;
+
+ ret = strict_strtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+ target_load = val;
+ return count;
+}
+
+static struct global_attr target_load_attr =
+ __ATTR(target_load, S_IRUGO | S_IWUSR,
+ show_target_load, store_target_load);
+
static ssize_t show_hispeed_freq(struct kobject *kobj,
struct attribute *attr, char *buf)
{
@@ -581,6 +609,7 @@ static struct global_attr boostpulse =
__ATTR(boostpulse, 0200, NULL, store_boostpulse);
static struct attribute *interactive_attributes[] = {
+ &target_load_attr.attr,
&hispeed_freq_attr.attr,
&go_hispeed_load_attr.attr,
&above_hispeed_delay.attr,