diff options
author | Thomas Renninger <trenn@suse.de> | 2008-09-01 08:27:03 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-09-22 18:50:52 -0400 |
commit | 2fd47094f92fa2bdbf99be33294a7b6b97785a70 (patch) | |
tree | bbab141fb80ed3d27ed0709d7671df00971be3ca /arch/x86 | |
parent | 910dfae298f7b3dae0e9a52736182a3b0559ca35 (diff) |
CPUFREQ: powernow-k8: Try to detect old BIOS, not supporting CPU freq on a recent AMD CPUs.
Make use of FW_BUG interface to give vendors and users the ability to
automatically check for powernow-k8 related BIOS bugs by:
dmesg |grep "Firmware Bug"
Signed-off-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 84bb395038d8..4e0c6abd7ca4 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #define PFX "powernow-k8: " | 47 | #define PFX "powernow-k8: " |
48 | #define BFX PFX "BIOS error: " | ||
49 | #define VERSION "version 2.20.00" | 48 | #define VERSION "version 2.20.00" |
50 | #include "powernow-k8.h" | 49 | #include "powernow-k8.h" |
51 | 50 | ||
@@ -536,35 +535,40 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 | |||
536 | 535 | ||
537 | for (j = 0; j < data->numps; j++) { | 536 | for (j = 0; j < data->numps; j++) { |
538 | if (pst[j].vid > LEAST_VID) { | 537 | if (pst[j].vid > LEAST_VID) { |
539 | printk(KERN_ERR PFX "vid %d invalid : 0x%x\n", j, pst[j].vid); | 538 | printk(KERN_ERR FW_BUG PFX "vid %d invalid : 0x%x\n", |
539 | j, pst[j].vid); | ||
540 | return -EINVAL; | 540 | return -EINVAL; |
541 | } | 541 | } |
542 | if (pst[j].vid < data->rvo) { /* vid + rvo >= 0 */ | 542 | if (pst[j].vid < data->rvo) { /* vid + rvo >= 0 */ |
543 | printk(KERN_ERR BFX "0 vid exceeded with pstate %d\n", j); | 543 | printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate" |
544 | " %d\n", j); | ||
544 | return -ENODEV; | 545 | return -ENODEV; |
545 | } | 546 | } |
546 | if (pst[j].vid < maxvid + data->rvo) { /* vid + rvo >= maxvid */ | 547 | if (pst[j].vid < maxvid + data->rvo) { /* vid + rvo >= maxvid */ |
547 | printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j); | 548 | printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate" |
549 | " %d\n", j); | ||
548 | return -ENODEV; | 550 | return -ENODEV; |
549 | } | 551 | } |
550 | if (pst[j].fid > MAX_FID) { | 552 | if (pst[j].fid > MAX_FID) { |
551 | printk(KERN_ERR BFX "maxfid exceeded with pstate %d\n", j); | 553 | printk(KERN_ERR FW_BUG PFX "maxfid exceeded with pstate" |
554 | " %d\n", j); | ||
552 | return -ENODEV; | 555 | return -ENODEV; |
553 | } | 556 | } |
554 | if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) { | 557 | if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) { |
555 | /* Only first fid is allowed to be in "low" range */ | 558 | /* Only first fid is allowed to be in "low" range */ |
556 | printk(KERN_ERR BFX "two low fids - %d : 0x%x\n", j, pst[j].fid); | 559 | printk(KERN_ERR FW_BUG PFX "two low fids - %d : " |
560 | "0x%x\n", j, pst[j].fid); | ||
557 | return -EINVAL; | 561 | return -EINVAL; |
558 | } | 562 | } |
559 | if (pst[j].fid < lastfid) | 563 | if (pst[j].fid < lastfid) |
560 | lastfid = pst[j].fid; | 564 | lastfid = pst[j].fid; |
561 | } | 565 | } |
562 | if (lastfid & 1) { | 566 | if (lastfid & 1) { |
563 | printk(KERN_ERR BFX "lastfid invalid\n"); | 567 | printk(KERN_ERR FW_BUG PFX "lastfid invalid\n"); |
564 | return -EINVAL; | 568 | return -EINVAL; |
565 | } | 569 | } |
566 | if (lastfid > LO_FID_TABLE_TOP) | 570 | if (lastfid > LO_FID_TABLE_TOP) |
567 | printk(KERN_INFO BFX "first fid not from lo freq table\n"); | 571 | printk(KERN_INFO FW_BUG PFX "first fid not from lo freq table\n"); |
568 | 572 | ||
569 | return 0; | 573 | return 0; |
570 | } | 574 | } |
@@ -672,13 +676,13 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
672 | 676 | ||
673 | dprintk("table vers: 0x%x\n", psb->tableversion); | 677 | dprintk("table vers: 0x%x\n", psb->tableversion); |
674 | if (psb->tableversion != PSB_VERSION_1_4) { | 678 | if (psb->tableversion != PSB_VERSION_1_4) { |
675 | printk(KERN_ERR BFX "PSB table is not v1.4\n"); | 679 | printk(KERN_ERR FW_BUG PFX "PSB table is not v1.4\n"); |
676 | return -ENODEV; | 680 | return -ENODEV; |
677 | } | 681 | } |
678 | 682 | ||
679 | dprintk("flags: 0x%x\n", psb->flags1); | 683 | dprintk("flags: 0x%x\n", psb->flags1); |
680 | if (psb->flags1) { | 684 | if (psb->flags1) { |
681 | printk(KERN_ERR BFX "unknown flags\n"); | 685 | printk(KERN_ERR FW_BUG PFX "unknown flags\n"); |
682 | return -ENODEV; | 686 | return -ENODEV; |
683 | } | 687 | } |
684 | 688 | ||
@@ -705,7 +709,7 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
705 | } | 709 | } |
706 | } | 710 | } |
707 | if (cpst != 1) { | 711 | if (cpst != 1) { |
708 | printk(KERN_ERR BFX "numpst must be 1\n"); | 712 | printk(KERN_ERR FW_BUG PFX "numpst must be 1\n"); |
709 | return -ENODEV; | 713 | return -ENODEV; |
710 | } | 714 | } |
711 | 715 | ||
@@ -1130,17 +1134,19 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1130 | "ACPI Processor module before starting this " | 1134 | "ACPI Processor module before starting this " |
1131 | "driver.\n"); | 1135 | "driver.\n"); |
1132 | #else | 1136 | #else |
1133 | printk(KERN_ERR PFX "Your BIOS does not provide ACPI " | 1137 | printk(KERN_ERR FW_BUG PFX "Your BIOS does not provide" |
1134 | "_PSS objects in a way that Linux understands. " | 1138 | " ACPI _PSS objects in a way that Linux " |
1135 | "Please report this to the Linux ACPI maintainers" | 1139 | "understands. Please report this to the Linux " |
1136 | " and complain to your BIOS vendor.\n"); | 1140 | "ACPI maintainers and complain to your BIOS " |
1141 | "vendor.\n"); | ||
1137 | #endif | 1142 | #endif |
1138 | kfree(data); | 1143 | kfree(data); |
1139 | return -ENODEV; | 1144 | return -ENODEV; |
1140 | } | 1145 | } |
1141 | if (pol->cpu != 0) { | 1146 | if (pol->cpu != 0) { |
1142 | printk(KERN_ERR PFX "No ACPI _PSS objects for CPU other than " | 1147 | printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " |
1143 | "CPU0. Complain to your BIOS vendor.\n"); | 1148 | "CPU other than CPU0. Complain to your BIOS " |
1149 | "vendor.\n"); | ||
1144 | kfree(data); | 1150 | kfree(data); |
1145 | return -ENODEV; | 1151 | return -ENODEV; |
1146 | } | 1152 | } |
@@ -1193,7 +1199,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1193 | 1199 | ||
1194 | /* min/max the cpu is capable of */ | 1200 | /* min/max the cpu is capable of */ |
1195 | if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) { | 1201 | if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) { |
1196 | printk(KERN_ERR PFX "invalid powernow_table\n"); | 1202 | printk(KERN_ERR FW_BUG PFX "invalid powernow_table\n"); |
1197 | powernow_k8_cpu_exit_acpi(data); | 1203 | powernow_k8_cpu_exit_acpi(data); |
1198 | kfree(data->powernow_table); | 1204 | kfree(data->powernow_table); |
1199 | kfree(data); | 1205 | kfree(data); |