[CPUFREQ] make ondemand governor aware of CPU domains

The following patch makes ondemand governor aware of policy->cpus.

policy->cpus mask lets multiple cpu use the same policy (useful where cpus 
share the frequency state), a recent change in cpufreq core.

Now ondemand governor looks at all cpus in policy->cpus and takes its 
frequency increase/decrease decisions based on most lightly loaded cpu in 
the group. This patch will not affect systems where policy->cpus contain
only one cpu.

Signed-off-by:: "Venkatesh Pallipadi" <venkatesh.pallipadi@intel.com>
Signed-off-by: Dominik Brodowski <linux@brodo.de>

diff -ruN linux-original/drivers/cpufreq/cpufreq_ondemand.c linux/drivers/cpufreq/cpufreq_ondemand.c
--- linux-original/drivers/cpufreq/cpufreq_ondemand.c	2004-11-27 12:06:53.600614160 +0100
+++ linux/drivers/cpufreq/cpufreq_ondemand.c	2004-11-27 12:30:34.153657272 +0100
@@ -229,10 +229,14 @@
 	static int down_skip[NR_CPUS];
 	struct cpu_dbs_info_s *this_dbs_info;
 
+	struct cpufreq_policy *policy;
+	unsigned int j;
+
 	this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
 	if (!this_dbs_info->enable)
 		return;
 
+	policy = this_dbs_info->cur_policy;
 	/* 
 	 * The default safe range is 20% to 80% 
 	 * Every sampling_rate, we check
@@ -246,12 +250,33 @@
 	 * Frequency reduction happens at minimum steps of 
 	 * 5% of max_frequency 
 	 */
+
 	/* Check for frequency increase */
 	total_idle_ticks = kstat_cpu(cpu).cpustat.idle +
 		kstat_cpu(cpu).cpustat.iowait;
 	idle_ticks = total_idle_ticks -
 		this_dbs_info->prev_cpu_idle_up;
 	this_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+	
+
+	for_each_cpu_mask(j, policy->cpus) {
+		unsigned int tmp_idle_ticks;
+		struct cpu_dbs_info_s *j_dbs_info;
+
+		if (j == cpu)
+			continue;
+
+		j_dbs_info = &per_cpu(cpu_dbs_info, j);
+		/* Check for frequency increase */
+		total_idle_ticks = kstat_cpu(j).cpustat.idle +
+			kstat_cpu(j).cpustat.iowait;
+		tmp_idle_ticks = total_idle_ticks -
+			j_dbs_info->prev_cpu_idle_up;
+		j_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+
+		if (tmp_idle_ticks < idle_ticks)
+			idle_ticks = tmp_idle_ticks;
+	}
 
 	/* Scale idle ticks by 100 and compare with up and down ticks */
 	idle_ticks *= 100;
@@ -259,8 +284,7 @@
 			sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate);
 
 	if (idle_ticks < up_idle_ticks) {
-		__cpufreq_driver_target(this_dbs_info->cur_policy,
-			this_dbs_info->cur_policy->max, 
+		__cpufreq_driver_target(policy, policy->max, 
 			CPUFREQ_RELATION_H);
 		down_skip[cpu] = 0;
 		this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
@@ -272,12 +296,34 @@
 	if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor)
 		return;
 
+	total_idle_ticks = kstat_cpu(cpu).cpustat.idle +
+		kstat_cpu(cpu).cpustat.iowait;
 	idle_ticks = total_idle_ticks -
 		this_dbs_info->prev_cpu_idle_down;
+	this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
+
+	for_each_cpu_mask(j, policy->cpus) {
+		unsigned int tmp_idle_ticks;
+		struct cpu_dbs_info_s *j_dbs_info;
+
+		if (j == cpu)
+			continue;
+
+		j_dbs_info = &per_cpu(cpu_dbs_info, j);
+		/* Check for frequency increase */
+		total_idle_ticks = kstat_cpu(j).cpustat.idle +
+			kstat_cpu(j).cpustat.iowait;
+		tmp_idle_ticks = total_idle_ticks -
+			j_dbs_info->prev_cpu_idle_down;
+		j_dbs_info->prev_cpu_idle_down = total_idle_ticks;
+
+		if (tmp_idle_ticks < idle_ticks)
+			idle_ticks = tmp_idle_ticks;
+	}
+
 	/* Scale idle ticks by 100 and compare with up and down ticks */
 	idle_ticks *= 100;
 	down_skip[cpu] = 0;
-	this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
 
 	freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
 		dbs_tuners_ins.sampling_down_factor;
@@ -285,14 +331,14 @@
 			sampling_rate_in_HZ(freq_down_sampling_rate);
 
 	if (idle_ticks > down_idle_ticks ) {
-		freq_down_step = (5 * this_dbs_info->cur_policy->max) / 100;
+		freq_down_step = (5 * policy->max) / 100;
 
 		/* max freq cannot be less than 100. But who knows.... */
 		if (unlikely(freq_down_step == 0))
 			freq_down_step = 5;
 
-		__cpufreq_driver_target(this_dbs_info->cur_policy,
-			this_dbs_info->cur_policy->cur - freq_down_step, 
+		__cpufreq_driver_target(policy,
+			policy->cur - freq_down_step, 
 			CPUFREQ_RELATION_H);
 		return;
 	}
@@ -328,6 +374,7 @@
 {
 	unsigned int cpu = policy->cpu;
 	struct cpu_dbs_info_s *this_dbs_info;
+	unsigned int j;
 
 	this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
 
@@ -344,14 +391,18 @@
 			break;
 		 
 		down(&dbs_sem);
-		this_dbs_info->cur_policy = policy;
+		for_each_cpu_mask(j, policy->cpus) {
+			struct cpu_dbs_info_s *j_dbs_info;
+			j_dbs_info = &per_cpu(cpu_dbs_info, j);
+			j_dbs_info->cur_policy = policy;
 		
-		this_dbs_info->prev_cpu_idle_up = 
-				kstat_cpu(cpu).cpustat.idle +
-				kstat_cpu(cpu).cpustat.iowait;
-		this_dbs_info->prev_cpu_idle_down = 
-				kstat_cpu(cpu).cpustat.idle +
-				kstat_cpu(cpu).cpustat.iowait;
+			j_dbs_info->prev_cpu_idle_up = 
+				kstat_cpu(j).cpustat.idle +
+				kstat_cpu(j).cpustat.iowait;
+			j_dbs_info->prev_cpu_idle_down = 
+				kstat_cpu(j).cpustat.idle +
+				kstat_cpu(j).cpustat.iowait;
+		}
 		this_dbs_info->enable = 1;
 		sysfs_create_group(&policy->kobj, &dbs_attr_group);
 		dbs_enable++;