
From: Dominik Brodowski <linux@dominikbrodowski.de>

From: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>

Check for lower limit of latency / sampling rate, and fix divide
underflows.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/cpufreq/cpufreq_ondemand.c |   23 +++++++++++++++++++----
 1 files changed, 19 insertions(+), 4 deletions(-)

diff -puN drivers/cpufreq/cpufreq_ondemand.c~cpufreq-ondemand-prevent-various-divide-underflows drivers/cpufreq/cpufreq_ondemand.c
--- 25/drivers/cpufreq/cpufreq_ondemand.c~cpufreq-ondemand-prevent-various-divide-underflows	Thu Sep 30 17:18:12 2004
+++ 25-akpm/drivers/cpufreq/cpufreq_ondemand.c	Thu Sep 30 17:18:12 2004
@@ -59,7 +59,7 @@ static unsigned int 				def_sampling_rat
 #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER	(1000)
 #define DEF_SAMPLING_DOWN_FACTOR		(10)
 #define TRANSITION_LATENCY_LIMIT		(10 * 1000)
-#define sampling_rate_in_HZ(x)			((x * HZ) / (1000 * 1000))
+#define sampling_rate_in_HZ(x)			(((x * HZ) < (1000 * 1000))?1:((x * HZ) / (1000 * 1000)))
 
 static void do_dbs_timer(void *data);
 
@@ -248,8 +248,10 @@ static void dbs_check_cpu(int cpu)
 		this_dbs_info->prev_cpu_idle_up;
 	this_dbs_info->prev_cpu_idle_up = kstat_cpu(cpu).cpustat.idle;
 
+	/* Scale idle ticks by 100 and compare with up and down ticks */
+	idle_ticks *= 100;
 	up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) *
-			sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate) / 100;
+			sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate);
 
 	if (idle_ticks < up_idle_ticks) {
 		__cpufreq_driver_target(this_dbs_info->cur_policy,
@@ -267,16 +269,23 @@ static void dbs_check_cpu(int cpu)
 
 	idle_ticks = kstat_cpu(cpu).cpustat.idle - 
 		this_dbs_info->prev_cpu_idle_down;
+	/* 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 = kstat_cpu(cpu).cpustat.idle;
 
 	freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
 		dbs_tuners_ins.sampling_down_factor;
 	down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) *
-			sampling_rate_in_HZ(freq_down_sampling_rate) / 100;
+			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;
+
+		/* 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_RELATION_H);
@@ -344,8 +353,14 @@ static int cpufreq_governor_dbs(struct c
 		 * is used for first time
 		 */
 		if (dbs_enable == 1) {
+			unsigned int latency;
 			/* policy latency is in nS. Convert it to uS first */
-			def_sampling_rate = (policy->cpuinfo.transition_latency / 1000) *
+
+			latency = policy->cpuinfo.transition_latency;
+			if (latency < 1000)
+				latency = 1000;
+
+			def_sampling_rate = (latency / 1000) *
 					DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
 			dbs_tuners_ins.sampling_rate = def_sampling_rate;
 
_
