diff -ru linux-original/arch/i386/kernel/cpu/cpufreq/longhaul.c linux/arch/i386/kernel/cpu/cpufreq/longhaul.c
--- linux-original/arch/i386/kernel/cpu/cpufreq/longhaul.c	2002-12-25 17:45:52.000000000 +0100
+++ linux/arch/i386/kernel/cpu/cpufreq/longhaul.c	2002-12-27 10:49:52.000000000 +0100
@@ -313,6 +313,10 @@
 	if ((!can_scale_fsb) && (newfsb != current_fsb))
 		return;
 
+	if (((clock_ratio[clock_ratio_index] * newfsb * 100) > highest_speed) ||
+	    ((clock_ratio[clock_ratio_index] * newfsb * 100) < lowest_speed))
+		return;
+
 	freqs.old = longhaul_get_cpu_mult() * longhaul_get_cpu_fsb() * 100;
 	freqs.new = clock_ratio[clock_ratio_index] * newfsb * 100;
 	freqs.cpu = 0; /* longhaul.c is UP only driver */
@@ -582,18 +586,68 @@
 
 	policy->max = newmax;
 
+	cpufreq_verify_within_limits(policy, lowest_speed, highest_speed);
+
+	return 0;
+}
+
+
+static int longhaul_get_best_freq_for_fsb(struct cpufreq_policy *policy, 
+					  unsigned int min_mult, 
+					  unsigned int max_mult, 
+					  unsigned int fsb, 
+					  unsigned int *new_mult)
+{
+	unsigned int optimal = 0;
+	unsigned int found_optimal = 0;
+	unsigned int i;
+
+	switch(policy->policy) {
+	case CPUFREQ_POLICY_POWERSAVE:
+		optimal = max_mult;
+		break;
+	case CPUFREQ_POLICY_PERFORMANCE:
+		optimal = min_mult;
+	}
+
+	for(i=0; i<numscales; i++) {
+		unsigned int freq = fsb * clock_ratio[i] * 100;
+		if ((freq > policy->max) ||
+		    (freq < policy->min))
+			continue;
+		switch(policy->policy) {
+		case CPUFREQ_POLICY_POWERSAVE:
+			if (clock_ratio[i] < clock_ratio[optimal]) {
+				found_optimal = 1;
+				optimal = i;
+			}
+			break;
+		case CPUFREQ_POLICY_PERFORMANCE:
+			if (clock_ratio[i] > clock_ratio[optimal]) {
+				found_optimal = 1;
+				optimal = i;
+			}
+			break;
+		}
+	}
+		
+	if (found_optimal) {
+		*new_mult = optimal;
+		return 1;
+	}
 	return 0;
 }
 
 
 static int longhaul_setpolicy (struct cpufreq_policy *policy)
 {
-	unsigned int    number_states = 0;
 	unsigned int    i;
 	unsigned int    fsb_index = 0;
 	unsigned int    new_fsb = 0;
 	unsigned int    new_clock_ratio = 0;
-	unsigned int    best_freq = -1;
+	unsigned int    min_mult = 0;
+	unsigned int    max_mult = 0;
+
 
 	if (!longhaul_driver)
 		return -EINVAL;
@@ -603,103 +657,36 @@
 	else
 		fsb_search_table = power_fsb_table;
 
+	for(i=0;i<numscales;i++) {
+		if (clock_ratio[max_mult] < clock_ratio[i])
+				max_mult = i;
+		else if (clock_ratio[min_mult] > clock_ratio[i])
+				min_mult = i;
+	}
+
 	if (can_scale_fsb==1) {
-		for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++) 
+		unsigned int found = 0;
+		for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++)
 		{
-			unsigned int tmpcount = longhaul_statecount_fsb(policy, fsb_search_table[fsb_index]);
-			if (tmpcount == 1)
+			if (longhaul_get_best_freq_for_fsb(policy, 
+			              min_mult, max_mult, 
+				      fsb_search_table[fsb_index], 
+				      &new_clock_ratio)) {
 				new_fsb = fsb_search_table[fsb_index];
-			number_states += tmpcount;
+				break;
+			}
 		}
+		if (!found)
+			return -EINVAL;
 	} else {
-		number_states = longhaul_statecount_fsb(policy, current_fsb);
 		new_fsb = current_fsb;
-	}
-
-	if (!number_states)
-		return -EINVAL;
-	else if (number_states == 1) {
-		for(i=0; i<numscales; i++) {
-			if ((clock_ratio[i] != -1) &&
-			    ((clock_ratio[i] * new_fsb * 100) <= policy->max) &&
-			    ((clock_ratio[i] * new_fsb * 100) >= policy->min))
-				new_clock_ratio = i;
-		}
-		longhaul_setstate(new_clock_ratio, new_fsb);
-	}
-
-	switch (policy->policy) {
-	case CPUFREQ_POLICY_POWERSAVE:
-		best_freq = -1;
-		if (can_scale_fsb==1) {
-			for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++) 
-			{
-				for(i=0; i<numscales; i++) {
-					unsigned int tmpfreq = fsb_search_table[fsb_index] * clock_ratio[i] * 100;
-					if (clock_ratio[i] == -1)
-						continue;
-
-					if ((tmpfreq >= policy->min) &&
-					    (tmpfreq <= policy->max) &&
-					    (tmpfreq < best_freq)) {
-						new_clock_ratio = i;
-						new_fsb = fsb_search_table[fsb_index];
-					}
-				}
-			}
-		} else {
-			for(i=0; i<numscales; i++) {
-				unsigned int tmpfreq = current_fsb * clock_ratio[i] * 100;
-					if (clock_ratio[i] == -1)
-						continue;
-
-					if ((tmpfreq >= policy->min) &&
-					    (tmpfreq <= policy->max) &&
-					    (tmpfreq < best_freq)) {
-						new_clock_ratio = i;
-						new_fsb = current_fsb;
-					}
-				}
-		}
-		break;
-	case CPUFREQ_POLICY_PERFORMANCE:
-		best_freq = 0;
-		if (can_scale_fsb==1) {
-			for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++) 
-			{
-				for(i=0; i<numscales; i++) {
-					unsigned int tmpfreq = fsb_search_table[fsb_index] * clock_ratio[i] * 100;
-					if (clock_ratio[i] == -1)
-						continue;
-
-					if ((tmpfreq >= policy->min) &&
-					    (tmpfreq <= policy->max) &&
-					    (tmpfreq > best_freq)) {
-						new_clock_ratio = i;
-						new_fsb = fsb_search_table[fsb_index];
-					}
-				}
-			}
-		} else {
-			for(i=0; i<numscales; i++) {
-				unsigned int tmpfreq = current_fsb * clock_ratio[i] * 100;
-					if (clock_ratio[i] == -1)
-						continue;
-
-					if ((tmpfreq >= policy->min) &&
-					    (tmpfreq <= policy->max) &&
-					    (tmpfreq > best_freq)) {
-						new_clock_ratio = i;
-						new_fsb = current_fsb;
-					}
-				}
-		}
-		break;
-	default:
-		return -EINVAL;
+		if (!longhaul_get_best_freq_for_fsb(policy, min_mult, 
+			     max_mult, new_fsb, &new_clock_ratio))
+			return -EINVAL;
 	}
 
 	longhaul_setstate(new_clock_ratio, new_fsb);
+
 	return 0;
 }
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/