From 69e99ffaf725e2a9acf6da3cfbf1605f49a9171f Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Fri, 14 Dec 2012 17:31:19 -0800 Subject: cpufreq: interactive: specify duration of CPU speed boost pulse Sysfs attribute boostpulse_duration specifies the duration of boosting CPU speed in response to bootpulse events. Duration is specified in usecs, default 80ms. Change-Id: Ifd41625574891a44f1787a4e85d1e7b4f2afb52b Signed-off-by: Todd Poynor --- drivers/cpufreq/cpufreq_interactive.c | 52 ++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index e6c8e6fb45f..604f06af6dc 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -94,11 +94,12 @@ static unsigned long timer_rate; #define DEFAULT_ABOVE_HISPEED_DELAY DEFAULT_TIMER_RATE static unsigned long above_hispeed_delay_val; -/* - * Non-zero means longer-term speed boost active. - */ - +/* Non-zero means indefinite speed boost active */ static int boost_val; +/* Duration of a boot pulse in usecs */ +static int boostpulse_duration_val = DEFAULT_MIN_SAMPLE_TIME; +/* End time of boost pulse in ktime converted to usecs */ +static u64 boostpulse_endtime; static bool governidle; module_param(governidle, bool, S_IWUSR | S_IRUGO); @@ -267,6 +268,7 @@ static void cpufreq_interactive_timer(unsigned long data) unsigned int loadadjfreq; unsigned int index; unsigned long flags; + bool boosted; smp_rmb(); @@ -285,8 +287,9 @@ static void cpufreq_interactive_timer(unsigned long data) do_div(cputime_speedadj, delta_time); loadadjfreq = (unsigned int)cputime_speedadj * 100; cpu_load = loadadjfreq / pcpu->target_freq; + boosted = boost_val || now < boostpulse_endtime; - if ((cpu_load >= go_hispeed_load || boost_val) && + if ((cpu_load >= go_hispeed_load || boosted) && pcpu->target_freq < hispeed_freq) new_freq = hispeed_freq; else @@ -326,8 +329,18 @@ static void cpufreq_interactive_timer(unsigned long data) } } - pcpu->floor_freq = new_freq; - pcpu->floor_validate_time = now; + /* + * Update the timestamp for checking whether speed has been held at + * or above the selected frequency for a minimum of min_sample_time, + * if not boosted to hispeed_freq. If boosted to hispeed_freq then we + * allow the speed to drop as soon as the boostpulse duration expires + * (or the indefinite boost is turned off). + */ + + if (!boosted || new_freq > hispeed_freq) { + pcpu->floor_freq = new_freq; + pcpu->floor_validate_time = now; + } if (pcpu->target_freq == new_freq) { trace_cpufreq_interactive_already( @@ -773,6 +786,7 @@ static ssize_t store_boostpulse(struct kobject *kobj, struct attribute *attr, if (ret < 0) return ret; + boostpulse_endtime = ktime_to_us(ktime_get()) + boostpulse_duration_val; trace_cpufreq_interactive_boost("pulse"); cpufreq_interactive_boost(); return count; @@ -781,6 +795,29 @@ static ssize_t store_boostpulse(struct kobject *kobj, struct attribute *attr, static struct global_attr boostpulse = __ATTR(boostpulse, 0200, NULL, store_boostpulse); +static ssize_t show_boostpulse_duration( + struct kobject *kobj, struct attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", boostpulse_duration_val); +} + +static ssize_t store_boostpulse_duration( + struct kobject *kobj, struct attribute *attr, const char *buf, + size_t count) +{ + int ret; + unsigned long val; + + ret = kstrtoul(buf, 0, &val); + if (ret < 0) + return ret; + + boostpulse_duration_val = val; + return count; +} + +define_one_global_rw(boostpulse_duration); + static struct attribute *interactive_attributes[] = { &target_loads_attr.attr, &hispeed_freq_attr.attr, @@ -790,6 +827,7 @@ static struct attribute *interactive_attributes[] = { &timer_rate_attr.attr, &boost.attr, &boostpulse.attr, + &boostpulse_duration.attr, NULL, }; -- cgit v1.2.3-54-g00ecf