summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/cpu-tegra3.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2012-04-28 23:25:39 -0700
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-05-09 05:03:43 -0700
commitc813274c51fc0d1c237737133f123f250aa37f67 (patch)
treeaf22adb5331609905d1b57d816a178cddc8c7d0e /arch/arm/mach-tegra/cpu-tegra3.c
parentd9ae4ef0984e3b1c1284e39d2ebf1c0558cfaa6f (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: Id545f8d48cbf380e24824a5adfe045ff68c1f39c Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/99708 Reviewed-by: Rohan Somvanshi <rsomvanshi@nvidia.com> Tested-by: Rohan Somvanshi <rsomvanshi@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/cpu-tegra3.c')
-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 d9535273ea7f..374a27156f02 100644
--- a/arch/arm/mach-tegra/cpu-tegra3.c
+++ b/arch/arm/mach-tegra/cpu-tegra3.c
@@ -217,6 +217,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);
@@ -228,19 +230,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) {
@@ -255,18 +255,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:
@@ -281,6 +277,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) {