Merge to Fedora kernel-2.6.7-1.492
[linux-2.6.git] / arch / i386 / kernel / cpu / cpufreq / powernow-k8.c
index 51c59ef..20d875d 100644 (file)
@@ -553,7 +553,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst,
                printk(KERN_ERR PFX "no p states to transition\n");
                return -ENODEV;
        }
-                                                                                                    
+
        if (check_pst_table(data, pst, maxvid))
                return -EINVAL;
 
@@ -733,12 +733,24 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
                        continue;
                }
 
-               /* verify only 1 entry from the lo frequency table */
-               if ((fid < HI_FID_TABLE_BOTTOM) && (cntlofreq++)) {
-                       printk(KERN_ERR PFX "Too many lo freq table entries\n");
-                       goto err_out;
+               if (fid < HI_FID_TABLE_BOTTOM) {
+                       if (cntlofreq) {
+                               /* if both entries are the same, ignore this
+                                * one... 
+                                */
+                               if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
+                                   (powernow_table[i].index != powernow_table[cntlofreq].index)) {
+                                       printk(KERN_ERR PFX "Too many lo freq table entries\n");
+                                       goto err_out_mem;
+                               }
+                               
+                               dprintk(KERN_INFO PFX "double low frequency table entry, ignoring it.\n");
+                               powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+                               continue;
+                       } else
+                               cntlofreq = i;
                }
-                                                                                                            
+
                if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
                        printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n",
                                powernow_table[i].frequency,
@@ -757,12 +769,16 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
        print_basics(data);
        powernow_k8_acpi_pst_values(data, 0);
        return 0;
+
+err_out_mem:
+       kfree(powernow_table);
+
 err_out:
        acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
 
        /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */
        data->acpi_data.state_count = 0;
-                                                                                                            
+
        return -ENODEV;
 }
 
@@ -853,12 +869,9 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
 
        if (smp_processor_id() != pol->cpu) {
                printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
-               goto sched_out;
+               goto err_out;
        }
 
-       /* from this point, do not exit without restoring preempt and cpu */
-       preempt_disable();
-
        if (pending_bit_stuck()) {
                printk(KERN_ERR PFX "failing targ, change pending bit set\n");
                goto err_out;
@@ -896,8 +909,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
        ret = 0;
 
 err_out:
-       preempt_enable_no_resched();
-sched_out:
        set_cpus_allowed(current, oldmask);
        schedule();
 
@@ -945,7 +956,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
                if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) {
                        printk(KERN_INFO PFX "MP systems not supported by PSB BIOS structure\n");
                        kfree(data);
-                       return 0;
+                       return -ENODEV;
                }
                rc = find_psb_table(data);
                if (rc) {
@@ -1013,7 +1024,7 @@ err_out:
        return -ENODEV;
 }
 
-static int __exit powernowk8_cpu_exit (struct cpufreq_policy *pol)
+static int powernowk8_cpu_exit (struct cpufreq_policy *pol)
 {
        struct powernow_k8_data *data = powernow_data[pol->cpu];
 
@@ -1047,7 +1058,7 @@ static unsigned int powernowk8_get (unsigned int cpu)
        if (query_current_values_with_pending_wait(data))
                goto out;
 
-       khz = find_khz_freq_from_fid(data->currfid);    
+       khz = find_khz_freq_from_fid(data->currfid);
 
  out:
        preempt_enable_no_resched();
@@ -1065,7 +1076,7 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
        .verify = powernowk8_verify,
        .target = powernowk8_target,
        .init = powernowk8_cpu_init,
-       .exit = powernowk8_cpu_exit,
+       .exit = __devexit_p(powernowk8_cpu_exit),
        .get = powernowk8_get,
        .name = "powernow-k8",
        .owner = THIS_MODULE,
@@ -1094,7 +1105,7 @@ static int __init powernowk8_init(void)
 }
 
 /* driver entry point for term */
-static void __exit powernowk8_exit(void)
+static void powernowk8_exit(void)
 {
        dprintk(KERN_INFO PFX "exit\n");