[Nexus 4 Original Android Development] franciscofranco:
Interesting. This is what I've been running for 2 days:

diff --git a/arch/arm/kernel/load_stats.c b/arch/arm/kernel/load_stats.c
index 6b65def..18bd5c3 100644
--- a/arch/arm/kernel/load_stats.c
+++ b/arch/arm/kernel/load_stats.c
@@ -139,9 +139,8 @@ static int update_average_load(unsigned int freq, unsigned int cpu)
return 0;
}

-unsigned int report_load_at_max_freq()
+unsigned int report_load_at_max_freq(int cpu)
{
-	int cpu = 0;
struct cpu_load_data *pcpu;
unsigned int total_load = 0;
pcpu = &per_cpu(cpuload, cpu);
@@ -157,14 +156,15 @@ static int __init msm_rq_stats_init(void)
{
int cpu = 0;
struct cpufreq_policy cpu_policy;
-	struct cpu_load_data *pcpu = &per_cpu(cpuload, cpu);
-
-	cpufreq_get_policy(&cpu_policy, cpu);
-
-	pcpu->policy_max = cpu_policy.max;
-	pcpu->cur_freq = acpuclk_get_rate(cpu);

-	cpumask_copy(pcpu->related_cpus, cpu_policy.cpus);
+	for_each_possible_cpu(cpu)
+	{
+	struct cpu_load_data *pcpu = &per_cpu(cpuload, cpu);
+	cpufreq_get_policy(&cpu_policy, cpu);
+	pcpu->policy_max = cpu_policy.max;
+	pcpu->cur_freq = acpuclk_get_rate(cpu);
+	cpumask_copy(pcpu->related_cpus, cpu_policy.cpus);
+	}

return 0;
}
diff --git a/arch/arm/kernel/mako_hotplug.c b/arch/arm/kernel/mako_hotplug.c
index 5bf8a50..2b88bc8 100644
--- a/arch/arm/kernel/mako_hotplug.c
+++ b/arch/arm/kernel/mako_hotplug.c
@@ -38,14 +38,14 @@ struct cpu_stats
unsigned int default_first_level;
unsigned int suspend_frequency;
unsigned int cores_on_touch;
+
+ unsigned int counter[2];
};

static struct cpu_stats stats;
static struct workqueue_struct *wq;
static struct delayed_work decide_hotplug;

-int counter;
-
static void scale_interactive_tunables(unsigned int above_hispeed_delay,
unsigned int timer_rate,
unsigned int min_sample_time)
@@ -60,18 +60,6 @@ static void decide_hotplug_func(struct work_struct *work)
int cpu;
int cpu_boost;

- if (report_load_at_max_freq() >= stats.default_first_level)
- {
- if (likely(counter < HIGH_LOAD_COUNTER))
- counter += 2;
- }
-
- else
- {
- if (counter > 0)
- counter--;
- }
-
if (unlikely(is_touching && num_online_cpus() < stats.cores_on_touch))
{
for_each_possible_cpu(cpu_boost)
@@ -82,35 +70,61 @@ static void decide_hotplug_func(struct work_struct *work)
}
}
}
+
+ for_each_online_cpu(cpu)
+ {
+ if (report_load_at_max_freq(cpu) >= stats.default_first_level)
+ {
+ if (likely(stats.counter[cpu] < HIGH_LOAD_COUNTER))
+ stats.counter[cpu] += 2;
+ }
+
+ else
+ {
+ if (stats.counter[cpu] > 0)
+ stats.counter[cpu]--;
+ }
+
+ if (cpu)
+ {
+ cpu = 0;
+ break;
+ }
+ }
+
+ if (stats.counter[0] >= 10)
+ {
+ if (!cpu_online(2))
+ {
+ cpu_up(2);
+ scale_interactive_tunables(0, 10000, 80000);
+ }
+ }
+ else
+ {
+ if (cpu_online(2))
+ {
+ cpu_down(2);
+ scale_interactive_tunables(20000, 40000, 20000);
+ }
+ }

- if (counter >= 10)
+ if (stats.counter[1] >= 10)
{
- if (num_online_cpus() < num_possible_cpus())
+ if (!cpu_online(3))
{
- for_each_possible_cpu(cpu)
- {
- if (!cpu_online(cpu))
- {
- cpu_up(cpu);
- }
- }
+ cpu_up(3);
scale_interactive_tunables(0, 10000, 80000);
}
}

else
{
- if (num_online_cpus() > 2 && !is_touching)
+ if (cpu_online(3))
{
- for_each_online_cpu(cpu)
- {
- if (cpu > 1)
- {
- cpu_down(cpu);
- }
- }
+ cpu_down(3);
scale_interactive_tunables(20000, 40000, 20000);
- }
+ }
}

queue_delayed_work(wq, &decide_hotplug, TIMER);
@@ -155,7 +169,8 @@ static void mako_hotplug_late_resume(struct early_suspend *handler)
}
}

- counter = 0;
+ stats.counter[0] = 0;
+ stats.counter[1] = 0;

/* restore max frequency */
msm_cpufreq_set_freq_limits(0, MSM_CPUFREQ_NO_LIMIT, MSM_CPUFREQ_NO_LIMIT);
@@ -213,6 +228,8 @@ int __init mako_hotplug_init(void)
stats.default_first_level = DEFAULT_FIRST_LEVEL;
stats.suspend_frequency = DEFAULT_SUSPEND_FREQ;
stats.cores_on_touch = DEFAULT_CORES_ON_TOUCH;
+ stats.counter[0] = 0;
+ stats.counter[1] = 0;

wq = alloc_workqueue("mako_hotplug_workqueue",
WQ_UNBOUND | WQ_RESCUER | WQ_FREEZABLE, 1);
diff --git a/include/linux/hotplug.h b/include/linux/hotplug.h
index f63c178..807d3a1 100644
--- a/include/linux/hotplug.h
+++ b/include/linux/hotplug.h
@@ -37,6 +37,6 @@ extern unsigned int get_hispeed_freq(void);
extern bool is_touching;
extern u64 freq_boosted_time;

-extern unsigned int report_load_at_max_freq(void);
+extern unsigned int report_load_at_max_freq(int cpu);

#endif
\ No newline at end of file