summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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) {