--- linux-2.6.24-git-tuxonice-r5/arch/x86/kernel/cpu/cpufreq/powernow-k8.c.orig	2007-10-13 15:44:07.000000000 +0200
+++ linux-2.6.24-git-tuxonice-r5/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2007-10-13 15:46:36.000000000 +0200
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/smp.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
@@ -49,6 +50,15 @@
 #define VERSION "version 2.00.00"
 #include "powernow-k8.h"
 
+static int vcore_list[16] = { 0 };
+static int vcore_list_count = 0;
+module_param_array(vcore_list, int, &vcore_list_count, 0644);
+MODULE_PARM_DESC(vcore_list, "List of new voltages to use, order must match freq_list");
+
+static int freq_list[16] = { 0 };
+static int freq_list_count = 0;
+module_param_array(freq_list, int, &freq_list_count, 0644);
+MODULE_PARM_DESC(freq_list, "List of new frequencies to use, order must match vcore_list");
 /* serialize freq changes  */
 static DEFINE_MUTEX(fidvid_mutex);
 
@@ -67,6 +77,12 @@
 }
 
 
+/* Return fid from a frequency in MHz */
+static u32 find_fid_from_freq(u32 freq)
+{
+	return (freq - 800) / 100;
+}
+
 /* Return a frequency in KHz, given an input fid */
 static u32 find_khz_freq_from_fid(u32 fid)
 {
@@ -98,6 +114,12 @@
 	return (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
 }
 
+/* Return a vid from a voltage in mV */
+static u32 find_vid_from_millivolts(u32 vcore)
+{
+	return (1550-vcore)/25;
+}
+
 /* Return the vco fid for an input fid
  *
  * Each "low" fid has corresponding "high" fid, and you can get to "low" fids
@@ -619,6 +641,7 @@
 
 static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid)
 {
+	printk(KERN_INFO PFX "fill_powernow_table() entry");
 	struct cpufreq_frequency_table *powernow_table;
 	unsigned int j;
 
@@ -642,13 +665,17 @@
 	if (check_pst_table(data, pst, maxvid))
 		return -EINVAL;
 
-	powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table)
-		* (data->numps + 1)), GFP_KERNEL);
+	if ( freq_list_count > data->numps )
+		data->numps = freq_list_count;
+	
+		powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (data->numps + 1)), GFP_KERNEL);
+
 	if (!powernow_table) {
 		printk(KERN_ERR PFX "powernow_table memory alloc failure\n");
 		return -ENOMEM;
 	}
 
+	if ( ( vcore_list_count <= 1 ) || ( freq_list_count <= 1 ) ) {
 	for (j = 0; j < data->numps; j++) {
 		powernow_table[j].index = pst[j].fid; /* lower 8 bits */
 		powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */
@@ -656,13 +683,34 @@
 	}
 	powernow_table[data->numps].frequency = CPUFREQ_TABLE_END;
 	powernow_table[data->numps].index = 0;
+		printk(KERN_INFO PFX "Wrong fucking side of things vcore:%d, freq:%d.\n",
+				vcore_list_count,
+				freq_list_count);		 
+	}
+	else {
+                for (j = 0; j < freq_list_count ; j++) {
+                	printk(KERN_INFO PFX "PTL: Requested %dMHz with %dmV\n",
+                                 freq_list[j],
+                                 vcore_list[j]);
+			powernow_table[j].index = find_fid_from_freq(freq_list[j]);
+			powernow_table[j].index |= (find_vid_from_millivolts(vcore_list[j]) << 8);
+			powernow_table[j].frequency = find_khz_freq_from_fid(find_fid_from_freq(freq_list[j]));
+				
+	
+		} /* for ( freq_list_count )*/
+			printk(KERN_INFO PFX "PTL: Performed required adjustments.\n");
+			powernow_table[freq_list_count].frequency = CPUFREQ_TABLE_END;
+			powernow_table[freq_list_count].index = 0;
+	}
+
+
 
 	if (query_current_values_with_pending_wait(data)) {
 		kfree(powernow_table);
 		return -EIO;
 	}
 
-	dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
+	printk(KERN_INFO PFX "cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
 	data->powernow_table = powernow_table;
 	if (first_cpu(cpu_core_map[data->cpu]) == data->cpu)
 		print_basics(data);
@@ -671,7 +719,7 @@
 		if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid))
 			return 0;
 
-	dprintk("currfid/vid do not match PST, ignoring\n");
+	printk(KERN_INFO PFX "currfid/vid do not match PST, ignoring\n");
 	return 0;
 }
 
@@ -798,8 +846,11 @@
 	}
 
 	/* fill in data->powernow_table */
-	powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table)
-		* (data->acpi_data.state_count + 1)), GFP_KERNEL);
+	if ( freq_list_count >  data->acpi_data.state_count ) 
+		data->acpi_data.state_count =  freq_list_count;
+
+		powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (data->acpi_data.state_count + 1)), GFP_KERNEL);
+
 	if (!powernow_table) {
 		dprintk("powernow_table memory alloc failure\n");
 		goto err_out;
@@ -899,9 +950,15 @@
 
 		dprintk("   %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
 
-		powernow_table[i].index = fid; /* lower 8 bits */
-		powernow_table[i].index |= (vid << 8); /* upper 8 bits */
-		powernow_table[i].frequency = find_khz_freq_from_fid(fid);
+		/* powernow_table[i].index = fid;  lower 8 bits 
+		powernow_table[i].index |= (vid << 8);  upper 8 bits 
+		powernow_table[i].frequency = find_khz_freq_from_fid(fid);*/
+		printk(KERN_INFO PFX "Requested %dMHz with %dmV\n",
+                               freq_list[i],
+                               vcore_list[i]);
+                powernow_table[i].index = find_fid_from_freq(freq_list[i]);
+                powernow_table[i].index |= (find_vid_from_millivolts(vcore_list[i]) << 8);
+                powernow_table[i].frequency = find_khz_freq_from_fid(find_fid_from_freq(freq_list[i]));
 
 		/* verify frequency is OK */
 		if ((powernow_table[i].frequency > (MAX_FREQ * 1000)) ||
@@ -939,6 +996,7 @@
 			printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n",
 				powernow_table[i].frequency,
 				(unsigned int) (data->acpi_data.states[i].core_frequency * 1000));
+			if ( ( freq_list_count <= 1 ) || ( !freq_list_count ) )
 			powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
 			continue;
 		}
