diff -urN oldtree/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c newtree/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
--- oldtree/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2006-03-27 13:28:15.000000000 -0500
+++ newtree/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2006-03-27 18:01:01.326779000 -0500
@@ -507,6 +507,148 @@
 static inline int centrino_cpu_early_init_acpi(void) { return 0; }
 #endif
 
+static int centrino_target (struct cpufreq_policy *policy,
+                          unsigned int target_freq,
+                          unsigned int relation);
+
+/************************** sysfs interface for user defined voltage table ************************/
+static ssize_t show_user_voltage (struct cpufreq_policy *policy, char *buf)
+{
+      ssize_t       bytes_written = 0;
+      unsigned int  cpu          = policy->cpu;
+      unsigned int  op_index     = 0;
+      unsigned int  voltage      = 0;
+
+      //dprintk("showing user voltage table in sysfs\n");
+
+      while (centrino_model[cpu]->op_points[op_index].frequency != CPUFREQ_TABLE_END)
+      {
+              //dprintk("getting state %i \n", i);
+              voltage = centrino_model[cpu]->op_points[op_index].index;
+              voltage = 700 + ((voltage & 0xFF) << 4);
+              //dprintk("writing voltage %i: %u mV \n", i, voltage);
+              bytes_written += snprintf (&buf[bytes_written],PAGE_SIZE, "%u",voltage);
+              op_index++;
+              if (centrino_model[cpu]->op_points[op_index].frequency != CPUFREQ_TABLE_END)
+                      bytes_written += snprintf (&buf[bytes_written],PAGE_SIZE, ",");
+              else
+                      bytes_written += snprintf (&buf[bytes_written],PAGE_SIZE, "\n");
+      }
+      buf[PAGE_SIZE-1] = 0;
+      return bytes_written;
+}
+
+static ssize_t
+store_user_voltage (struct cpufreq_policy *policy, const char *buf, size_t count)
+{
+      unsigned int  cpu;
+      const char   *curr_buf;
+      unsigned int  curr_freq;
+      unsigned int  op_index;
+      int           i;
+      int           isok;
+      char         *next_buf;
+      unsigned int  op_point;
+      ssize_t       retval;
+      unsigned int  voltage;
+
+      static struct cpufreq_frequency_table **original_table = NULL;
+
+      if (!policy)
+          return -ENODEV;
+      cpu = policy->cpu;
+      if (!centrino_model[cpu] || !centrino_model[cpu]->op_points)
+          return -ENODEV;
+
+      if (!original_table)
+      {
+              original_table = kmalloc(sizeof(struct cpufreq_frequency_table *)*NR_CPUS, GFP_KERNEL);
+              for (i=0; i < NR_CPUS; i++)
+              {
+                      original_table[i] = NULL;
+              }
+      }
+
+      if (!original_table[cpu])
+      {
+              /* Count number of frequencies and allocate memory for a copy */
+              for (i=0; centrino_model[cpu]->op_points[i].frequency != CPUFREQ_TABLE_END; i++);
+              /* Allocate memory to store the copy */
+              original_table[cpu] = (struct cpufreq_frequency_table*) kmalloc(sizeof(struct cpufreq_frequency_table)*(i+1), G$+               /* Make copy of frequency/voltage pairs */
+              for (i=0; centrino_model[cpu]->op_points[i].frequency != CPUFREQ_TABLE_END; i++)
+              {
+                      original_table[cpu][i].frequency = centrino_model[cpu]->op_points[i].frequency;
+                      original_table[cpu][i].index = centrino_model[cpu]->op_points[i].index;
+              }
+              original_table[cpu][i].frequency = CPUFREQ_TABLE_END;
+      }
+
+      op_index = 0;
+      curr_buf = buf;
+      next_buf = NULL;
+      isok     = 1;
+
+      while ((centrino_model[cpu]->op_points[op_index].frequency != CPUFREQ_TABLE_END)
+              && (isok))
+      {
+              voltage = simple_strtoul(curr_buf, &next_buf, 10);
+              if ((next_buf != curr_buf) && (next_buf != NULL))
+              {
+                      if ((voltage >= 700) && (voltage<=1600))
+                      {
+                              voltage = ((voltage - 700) >> 4) & 0xFF;
+                              op_point = (original_table[cpu])[op_index].index;
+                              if (voltage <= (op_point & 0xFF))
+                              {
+                                      //dprintk("setting control value %i to %04x\n", op_index, op_point);
+                                      op_point = (op_point & 0xFFFFFF00) | voltage;
+                                      centrino_model[cpu]->op_points[op_index].index = op_point;
+                              }
+                              else
+                              {
+                                      op_point = (op_point & 0xFFFFFF00) | voltage;
+                                      dprintk("not setting control value %i to %04x because requested voltage is not lower th$+                                       //isok = 0;
+                              }
+                      }
+                      else
+                      {
+                              dprintk("voltage value %i is out of bounds: %u mV\n", op_index, voltage);
+                              isok = 0;
+                      }
+                      curr_buf = next_buf;
+                      if (*curr_buf==',')
+                              curr_buf++;
+                      next_buf = NULL;
+              }
+              else
+              {
+                      dprintk("failed to parse voltage value %i\n", op_index);
+                      isok = 0;
+              }
+              op_index++;
+      }
+
+      if (isok)
+      {
+              retval = count;
+              curr_freq = cpufreq_get(policy->cpu);
+              centrino_target(policy, curr_freq, CPUFREQ_RELATION_L);
+      }
+      else
+      {
+              retval = -EINVAL;
+      }
+
+      return retval;
+}
+
+static struct freq_attr centrino_freq_attr_voltage_table =
+{
+      .attr = { .name = "voltage_table", .mode = 0644, .owner = THIS_MODULE },
+      .show = show_user_voltage,
+      .store = store_user_voltage,
+};
+
 static int centrino_cpu_init(struct cpufreq_policy *policy)
 {
 	struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
@@ -758,6 +900,7 @@
 
 static struct freq_attr* centrino_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
+	&centrino_freq_attr_voltage_table,
 	NULL,
 };
 
