summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2012-04-28 23:25:39 -0700
committerVarun Colbert <vcolbert@nvidia.com>2012-05-01 17:01:45 -0700
commitce8006db5ef53f32d0ce0d4f65f5537b3fb320ee (patch)
tree57d5c8d4c92878a8cd6857519ed90f5bc88ef139
parent1827824d541eef3899122e9040e0662042d935d1 (diff)
ARM: tegra: power: Apply down delay to balancing CPUs
On Tegra3 secondary G-CPU may be turned off by auto-hotplug governor in two cases: when overall CPU load is low enough to justify transition to LP CPU, or when CPU cores usage by the scheduler is unbalanced (skewed). In the former case down delay (currently 2sec) was inserted before the core is turned Off. In the latter case the up delay (100ms) was used, i.e., the same delay applied to balancing cores regardless of the On/Off direction. This commit would apply down delay when turning core Off in both cases above, and keep using up delay only for turning core On. Change-Id: I3ac01c4df833eaf020966d561ec4b9802e25b529 Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/99737 Tested-by: Jay Cheng <jacheng@nvidia.com> Reviewed-by: Prajakta Gudadhe <pgudadhe@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/cpu-tegra3.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/arch/arm/mach-tegra/cpu-tegra3.c b/arch/arm/mach-tegra/cpu-tegra3.c
index 76ff94435a13..f002803134a8 100644
--- a/arch/arm/mach-tegra/cpu-tegra3.c
+++ b/arch/arm/mach-tegra/cpu-tegra3.c
@@ -214,6 +214,8 @@ static void tegra_auto_hotplug_work_func(struct work_struct *work)
{
bool up = false;
unsigned int cpu = nr_cpu_ids;
+ unsigned long now = jiffies;
+ static unsigned long last_change_time;
mutex_lock(tegra3_cpu_lock);
@@ -225,19 +227,17 @@ static void tegra_auto_hotplug_work_func(struct work_struct *work)
cpu = tegra_get_slowest_cpu_n();
if (cpu < nr_cpu_ids) {
up = false;
- queue_delayed_work(
- hotplug_wq, &hotplug_work, down_delay);
- hp_stats_update(cpu, false);
} else if (!is_lp_cluster() && !no_lp) {
if(!clk_set_parent(cpu_clk, cpu_lp_clk)) {
hp_stats_update(CONFIG_NR_CPUS, true);
hp_stats_update(0, false);
/* catch-up with governor target speed */
tegra_cpu_set_speed_cap(NULL);
- } else
- queue_delayed_work(
- hotplug_wq, &hotplug_work, down_delay);
+ break;
+ }
}
+ queue_delayed_work(
+ hotplug_wq, &hotplug_work, down_delay);
break;
case TEGRA_HP_UP:
if (is_lp_cluster() && !no_lp) {
@@ -252,18 +252,14 @@ static void tegra_auto_hotplug_work_func(struct work_struct *work)
/* cpu speed is up and balanced - one more on-line */
case TEGRA_CPU_SPEED_BALANCED:
cpu = cpumask_next_zero(0, cpu_online_mask);
- if (cpu < nr_cpu_ids) {
+ if (cpu < nr_cpu_ids)
up = true;
- hp_stats_update(cpu, true);
- }
break;
/* cpu speed is up, but skewed - remove one core */
case TEGRA_CPU_SPEED_SKEWED:
cpu = tegra_get_slowest_cpu_n();
- if (cpu < nr_cpu_ids) {
+ if (cpu < nr_cpu_ids)
up = false;
- hp_stats_update(cpu, false);
- }
break;
/* cpu speed is up, but under-utilized - do nothing */
case TEGRA_CPU_SPEED_BIASED:
@@ -278,6 +274,14 @@ static void tegra_auto_hotplug_work_func(struct work_struct *work)
pr_err("%s: invalid tegra hotplug state %d\n",
__func__, hp_state);
}
+
+ if (!up && ((now - last_change_time) < down_delay))
+ cpu = nr_cpu_ids;
+
+ if (cpu < nr_cpu_ids) {
+ last_change_time = now;
+ hp_stats_update(cpu, up);
+ }
mutex_unlock(tegra3_cpu_lock);
if (cpu < nr_cpu_ids) {