diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 109 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.h | 3 | ||||
-rw-r--r-- | arch/x86/mach-rdc321x/platform.c | 1 | ||||
-rw-r--r-- | arch/x86/pci/irq.c | 2 | ||||
-rw-r--r-- | arch/x86/pci/legacy.c | 2 | ||||
-rw-r--r-- | arch/x86/pci/mmconfig-shared.c | 65 |
6 files changed, 88 insertions, 94 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 4e7271999a74..84bb395038d8 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -737,63 +737,44 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
737 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI | 737 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI |
738 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) | 738 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) |
739 | { | 739 | { |
740 | if (!data->acpi_data->state_count || (cpu_family == CPU_HW_PSTATE)) | 740 | if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) |
741 | return; | 741 | return; |
742 | 742 | ||
743 | data->irt = (data->acpi_data->states[index].control >> IRT_SHIFT) & IRT_MASK; | 743 | data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; |
744 | data->rvo = (data->acpi_data->states[index].control >> RVO_SHIFT) & RVO_MASK; | 744 | data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK; |
745 | data->exttype = (data->acpi_data->states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK; | 745 | data->exttype = (data->acpi_data.states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK; |
746 | data->plllock = (data->acpi_data->states[index].control >> PLL_L_SHIFT) & PLL_L_MASK; | 746 | data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK; |
747 | data->vidmvs = 1 << ((data->acpi_data->states[index].control >> MVS_SHIFT) & MVS_MASK); | 747 | data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK); |
748 | data->vstable = (data->acpi_data->states[index].control >> VST_SHIFT) & VST_MASK; | 748 | data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK; |
749 | } | ||
750 | |||
751 | |||
752 | static struct acpi_processor_performance *acpi_perf_data; | ||
753 | static int preregister_valid; | ||
754 | |||
755 | static int powernow_k8_cpu_preinit_acpi(void) | ||
756 | { | ||
757 | acpi_perf_data = alloc_percpu(struct acpi_processor_performance); | ||
758 | if (!acpi_perf_data) | ||
759 | return -ENODEV; | ||
760 | |||
761 | if (acpi_processor_preregister_performance(acpi_perf_data)) | ||
762 | return -ENODEV; | ||
763 | else | ||
764 | preregister_valid = 1; | ||
765 | return 0; | ||
766 | } | 749 | } |
767 | 750 | ||
768 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | 751 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) |
769 | { | 752 | { |
770 | struct cpufreq_frequency_table *powernow_table; | 753 | struct cpufreq_frequency_table *powernow_table; |
771 | int ret_val; | 754 | int ret_val; |
772 | int cpu = 0; | ||
773 | 755 | ||
774 | data->acpi_data = percpu_ptr(acpi_perf_data, cpu); | 756 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { |
775 | if (acpi_processor_register_performance(data->acpi_data, data->cpu)) { | ||
776 | dprintk("register performance failed: bad ACPI data\n"); | 757 | dprintk("register performance failed: bad ACPI data\n"); |
777 | return -EIO; | 758 | return -EIO; |
778 | } | 759 | } |
779 | 760 | ||
780 | /* verify the data contained in the ACPI structures */ | 761 | /* verify the data contained in the ACPI structures */ |
781 | if (data->acpi_data->state_count <= 1) { | 762 | if (data->acpi_data.state_count <= 1) { |
782 | dprintk("No ACPI P-States\n"); | 763 | dprintk("No ACPI P-States\n"); |
783 | goto err_out; | 764 | goto err_out; |
784 | } | 765 | } |
785 | 766 | ||
786 | if ((data->acpi_data->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || | 767 | if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || |
787 | (data->acpi_data->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { | 768 | (data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { |
788 | dprintk("Invalid control/status registers (%x - %x)\n", | 769 | dprintk("Invalid control/status registers (%x - %x)\n", |
789 | data->acpi_data->control_register.space_id, | 770 | data->acpi_data.control_register.space_id, |
790 | data->acpi_data->status_register.space_id); | 771 | data->acpi_data.status_register.space_id); |
791 | goto err_out; | 772 | goto err_out; |
792 | } | 773 | } |
793 | 774 | ||
794 | /* fill in data->powernow_table */ | 775 | /* fill in data->powernow_table */ |
795 | powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) | 776 | powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) |
796 | * (data->acpi_data->state_count + 1)), GFP_KERNEL); | 777 | * (data->acpi_data.state_count + 1)), GFP_KERNEL); |
797 | if (!powernow_table) { | 778 | if (!powernow_table) { |
798 | dprintk("powernow_table memory alloc failure\n"); | 779 | dprintk("powernow_table memory alloc failure\n"); |
799 | goto err_out; | 780 | goto err_out; |
@@ -806,12 +787,12 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
806 | if (ret_val) | 787 | if (ret_val) |
807 | goto err_out_mem; | 788 | goto err_out_mem; |
808 | 789 | ||
809 | powernow_table[data->acpi_data->state_count].frequency = CPUFREQ_TABLE_END; | 790 | powernow_table[data->acpi_data.state_count].frequency = CPUFREQ_TABLE_END; |
810 | powernow_table[data->acpi_data->state_count].index = 0; | 791 | powernow_table[data->acpi_data.state_count].index = 0; |
811 | data->powernow_table = powernow_table; | 792 | data->powernow_table = powernow_table; |
812 | 793 | ||
813 | /* fill in data */ | 794 | /* fill in data */ |
814 | data->numps = data->acpi_data->state_count; | 795 | data->numps = data->acpi_data.state_count; |
815 | if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu) | 796 | if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu) |
816 | print_basics(data); | 797 | print_basics(data); |
817 | powernow_k8_acpi_pst_values(data, 0); | 798 | powernow_k8_acpi_pst_values(data, 0); |
@@ -819,31 +800,16 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
819 | /* notify BIOS that we exist */ | 800 | /* notify BIOS that we exist */ |
820 | acpi_processor_notify_smm(THIS_MODULE); | 801 | acpi_processor_notify_smm(THIS_MODULE); |
821 | 802 | ||
822 | /* determine affinity, from ACPI if available */ | ||
823 | if (preregister_valid) { | ||
824 | if ((data->acpi_data->shared_type == CPUFREQ_SHARED_TYPE_ALL) || | ||
825 | (data->acpi_data->shared_type == CPUFREQ_SHARED_TYPE_ANY)) | ||
826 | data->starting_core_affinity = data->acpi_data->shared_cpu_map; | ||
827 | else | ||
828 | data->starting_core_affinity = cpumask_of_cpu(data->cpu); | ||
829 | } else { | ||
830 | /* best guess from family if not */ | ||
831 | if (cpu_family == CPU_HW_PSTATE) | ||
832 | data->starting_core_affinity = cpumask_of_cpu(data->cpu); | ||
833 | else | ||
834 | data->starting_core_affinity = per_cpu(cpu_core_map, data->cpu); | ||
835 | } | ||
836 | |||
837 | return 0; | 803 | return 0; |
838 | 804 | ||
839 | err_out_mem: | 805 | err_out_mem: |
840 | kfree(powernow_table); | 806 | kfree(powernow_table); |
841 | 807 | ||
842 | err_out: | 808 | err_out: |
843 | acpi_processor_unregister_performance(data->acpi_data, data->cpu); | 809 | acpi_processor_unregister_performance(&data->acpi_data, data->cpu); |
844 | 810 | ||
845 | /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */ | 811 | /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */ |
846 | data->acpi_data->state_count = 0; | 812 | data->acpi_data.state_count = 0; |
847 | 813 | ||
848 | return -ENODEV; | 814 | return -ENODEV; |
849 | } | 815 | } |
@@ -855,10 +821,10 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpuf | |||
855 | rdmsr(MSR_PSTATE_CUR_LIMIT, hi, lo); | 821 | rdmsr(MSR_PSTATE_CUR_LIMIT, hi, lo); |
856 | data->max_hw_pstate = (hi & HW_PSTATE_MAX_MASK) >> HW_PSTATE_MAX_SHIFT; | 822 | data->max_hw_pstate = (hi & HW_PSTATE_MAX_MASK) >> HW_PSTATE_MAX_SHIFT; |
857 | 823 | ||
858 | for (i = 0; i < data->acpi_data->state_count; i++) { | 824 | for (i = 0; i < data->acpi_data.state_count; i++) { |
859 | u32 index; | 825 | u32 index; |
860 | 826 | ||
861 | index = data->acpi_data->states[i].control & HW_PSTATE_MASK; | 827 | index = data->acpi_data.states[i].control & HW_PSTATE_MASK; |
862 | if (index > data->max_hw_pstate) { | 828 | if (index > data->max_hw_pstate) { |
863 | printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index); | 829 | printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index); |
864 | printk(KERN_ERR PFX "Please report to BIOS manufacturer\n"); | 830 | printk(KERN_ERR PFX "Please report to BIOS manufacturer\n"); |
@@ -874,7 +840,7 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpuf | |||
874 | 840 | ||
875 | powernow_table[i].index = index; | 841 | powernow_table[i].index = index; |
876 | 842 | ||
877 | powernow_table[i].frequency = data->acpi_data->states[i].core_frequency * 1000; | 843 | powernow_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000; |
878 | } | 844 | } |
879 | return 0; | 845 | return 0; |
880 | } | 846 | } |
@@ -883,16 +849,16 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf | |||
883 | { | 849 | { |
884 | int i; | 850 | int i; |
885 | int cntlofreq = 0; | 851 | int cntlofreq = 0; |
886 | for (i = 0; i < data->acpi_data->state_count; i++) { | 852 | for (i = 0; i < data->acpi_data.state_count; i++) { |
887 | u32 fid; | 853 | u32 fid; |
888 | u32 vid; | 854 | u32 vid; |
889 | 855 | ||
890 | if (data->exttype) { | 856 | if (data->exttype) { |
891 | fid = data->acpi_data->states[i].status & EXT_FID_MASK; | 857 | fid = data->acpi_data.states[i].status & EXT_FID_MASK; |
892 | vid = (data->acpi_data->states[i].status >> VID_SHIFT) & EXT_VID_MASK; | 858 | vid = (data->acpi_data.states[i].status >> VID_SHIFT) & EXT_VID_MASK; |
893 | } else { | 859 | } else { |
894 | fid = data->acpi_data->states[i].control & FID_MASK; | 860 | fid = data->acpi_data.states[i].control & FID_MASK; |
895 | vid = (data->acpi_data->states[i].control >> VID_SHIFT) & VID_MASK; | 861 | vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; |
896 | } | 862 | } |
897 | 863 | ||
898 | dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); | 864 | dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); |
@@ -933,10 +899,10 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf | |||
933 | cntlofreq = i; | 899 | cntlofreq = i; |
934 | } | 900 | } |
935 | 901 | ||
936 | if (powernow_table[i].frequency != (data->acpi_data->states[i].core_frequency * 1000)) { | 902 | if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { |
937 | printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n", | 903 | printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n", |
938 | powernow_table[i].frequency, | 904 | powernow_table[i].frequency, |
939 | (unsigned int) (data->acpi_data->states[i].core_frequency * 1000)); | 905 | (unsigned int) (data->acpi_data.states[i].core_frequency * 1000)); |
940 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 906 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; |
941 | continue; | 907 | continue; |
942 | } | 908 | } |
@@ -946,12 +912,11 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf | |||
946 | 912 | ||
947 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) | 913 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) |
948 | { | 914 | { |
949 | if (data->acpi_data->state_count) | 915 | if (data->acpi_data.state_count) |
950 | acpi_processor_unregister_performance(data->acpi_data, data->cpu); | 916 | acpi_processor_unregister_performance(&data->acpi_data, data->cpu); |
951 | } | 917 | } |
952 | 918 | ||
953 | #else | 919 | #else |
954 | static int powernow_k8_cpu_preinit_acpi(void) { return -ENODEV; } | ||
955 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; } | 920 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; } |
956 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; } | 921 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; } |
957 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; } | 922 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; } |
@@ -1136,7 +1101,7 @@ static int powernowk8_verify(struct cpufreq_policy *pol) | |||
1136 | static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | 1101 | static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) |
1137 | { | 1102 | { |
1138 | struct powernow_k8_data *data; | 1103 | struct powernow_k8_data *data; |
1139 | cpumask_t oldmask = CPU_MASK_ALL; | 1104 | cpumask_t oldmask; |
1140 | int rc; | 1105 | int rc; |
1141 | 1106 | ||
1142 | if (!cpu_online(pol->cpu)) | 1107 | if (!cpu_online(pol->cpu)) |
@@ -1209,7 +1174,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1209 | /* run on any CPU again */ | 1174 | /* run on any CPU again */ |
1210 | set_cpus_allowed_ptr(current, &oldmask); | 1175 | set_cpus_allowed_ptr(current, &oldmask); |
1211 | 1176 | ||
1212 | pol->cpus = data->starting_core_affinity; | 1177 | if (cpu_family == CPU_HW_PSTATE) |
1178 | pol->cpus = cpumask_of_cpu(pol->cpu); | ||
1179 | else | ||
1180 | pol->cpus = per_cpu(cpu_core_map, pol->cpu); | ||
1213 | data->available_cores = &(pol->cpus); | 1181 | data->available_cores = &(pol->cpus); |
1214 | 1182 | ||
1215 | /* Take a crude guess here. | 1183 | /* Take a crude guess here. |
@@ -1332,7 +1300,6 @@ static int __cpuinit powernowk8_init(void) | |||
1332 | } | 1300 | } |
1333 | 1301 | ||
1334 | if (supported_cpus == num_online_cpus()) { | 1302 | if (supported_cpus == num_online_cpus()) { |
1335 | powernow_k8_cpu_preinit_acpi(); | ||
1336 | printk(KERN_INFO PFX "Found %d %s " | 1303 | printk(KERN_INFO PFX "Found %d %s " |
1337 | "processors (%d cpu cores) (" VERSION ")\n", | 1304 | "processors (%d cpu cores) (" VERSION ")\n", |
1338 | num_online_nodes(), | 1305 | num_online_nodes(), |
@@ -1349,10 +1316,6 @@ static void __exit powernowk8_exit(void) | |||
1349 | dprintk("exit\n"); | 1316 | dprintk("exit\n"); |
1350 | 1317 | ||
1351 | cpufreq_unregister_driver(&cpufreq_amd64_driver); | 1318 | cpufreq_unregister_driver(&cpufreq_amd64_driver); |
1352 | |||
1353 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI | ||
1354 | free_percpu(acpi_perf_data); | ||
1355 | #endif | ||
1356 | } | 1319 | } |
1357 | 1320 | ||
1358 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>"); | 1321 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>"); |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h index a62612cd4be8..ab48cfed4d96 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h | |||
@@ -33,13 +33,12 @@ struct powernow_k8_data { | |||
33 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI | 33 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI |
34 | /* the acpi table needs to be kept. it's only available if ACPI was | 34 | /* the acpi table needs to be kept. it's only available if ACPI was |
35 | * used to determine valid frequency/vid/fid states */ | 35 | * used to determine valid frequency/vid/fid states */ |
36 | struct acpi_processor_performance *acpi_data; | 36 | struct acpi_processor_performance acpi_data; |
37 | #endif | 37 | #endif |
38 | /* we need to keep track of associated cores, but let cpufreq | 38 | /* we need to keep track of associated cores, but let cpufreq |
39 | * handle hotplug events - so just point at cpufreq pol->cpus | 39 | * handle hotplug events - so just point at cpufreq pol->cpus |
40 | * structure */ | 40 | * structure */ |
41 | cpumask_t *available_cores; | 41 | cpumask_t *available_cores; |
42 | cpumask_t starting_core_affinity; | ||
43 | }; | 42 | }; |
44 | 43 | ||
45 | 44 | ||
diff --git a/arch/x86/mach-rdc321x/platform.c b/arch/x86/mach-rdc321x/platform.c index a037041817c7..4f4e50c3ad3b 100644 --- a/arch/x86/mach-rdc321x/platform.c +++ b/arch/x86/mach-rdc321x/platform.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/list.h> | 25 | #include <linux/list.h> |
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/version.h> | ||
29 | #include <linux/leds.h> | 28 | #include <linux/leds.h> |
30 | 29 | ||
31 | #include <asm/gpio.h> | 30 | #include <asm/gpio.h> |
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index fec0123b33a9..8e077185e185 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
@@ -590,6 +590,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route | |||
590 | case PCI_DEVICE_ID_INTEL_ICH10_1: | 590 | case PCI_DEVICE_ID_INTEL_ICH10_1: |
591 | case PCI_DEVICE_ID_INTEL_ICH10_2: | 591 | case PCI_DEVICE_ID_INTEL_ICH10_2: |
592 | case PCI_DEVICE_ID_INTEL_ICH10_3: | 592 | case PCI_DEVICE_ID_INTEL_ICH10_3: |
593 | case PCI_DEVICE_ID_INTEL_PCH_0: | ||
594 | case PCI_DEVICE_ID_INTEL_PCH_1: | ||
593 | r->name = "PIIX/ICH"; | 595 | r->name = "PIIX/ICH"; |
594 | r->get = pirq_piix_get; | 596 | r->get = pirq_piix_get; |
595 | r->set = pirq_piix_set; | 597 | r->set = pirq_piix_set; |
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index ec9ce35e44d6..b722dd481b39 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c | |||
@@ -14,7 +14,7 @@ static void __devinit pcibios_fixup_peer_bridges(void) | |||
14 | int n, devfn; | 14 | int n, devfn; |
15 | long node; | 15 | long node; |
16 | 16 | ||
17 | if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff) | 17 | if (pcibios_last_bus <= 0 || pcibios_last_bus > 0xff) |
18 | return; | 18 | return; |
19 | DBG("PCI: Peer bridge fixup\n"); | 19 | DBG("PCI: Peer bridge fixup\n"); |
20 | 20 | ||
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 2bd5c53f6386..d9635764ce3d 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -293,7 +293,7 @@ static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl, | |||
293 | return AE_OK; | 293 | return AE_OK; |
294 | } | 294 | } |
295 | 295 | ||
296 | static int __init is_acpi_reserved(unsigned long start, unsigned long end) | 296 | static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used) |
297 | { | 297 | { |
298 | struct resource mcfg_res; | 298 | struct resource mcfg_res; |
299 | 299 | ||
@@ -310,6 +310,41 @@ static int __init is_acpi_reserved(unsigned long start, unsigned long end) | |||
310 | return mcfg_res.flags; | 310 | return mcfg_res.flags; |
311 | } | 311 | } |
312 | 312 | ||
313 | typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); | ||
314 | |||
315 | static int __init is_mmconf_reserved(check_reserved_t is_reserved, | ||
316 | u64 addr, u64 size, int i, | ||
317 | typeof(pci_mmcfg_config[0]) *cfg, int with_e820) | ||
318 | { | ||
319 | u64 old_size = size; | ||
320 | int valid = 0; | ||
321 | |||
322 | while (!is_reserved(addr, addr + size - 1, E820_RESERVED)) { | ||
323 | size >>= 1; | ||
324 | if (size < (16UL<<20)) | ||
325 | break; | ||
326 | } | ||
327 | |||
328 | if (size >= (16UL<<20) || size == old_size) { | ||
329 | printk(KERN_NOTICE | ||
330 | "PCI: MCFG area at %Lx reserved in %s\n", | ||
331 | addr, with_e820?"E820":"ACPI motherboard resources"); | ||
332 | valid = 1; | ||
333 | |||
334 | if (old_size != size) { | ||
335 | /* update end_bus_number */ | ||
336 | cfg->end_bus_number = cfg->start_bus_number + ((size>>20) - 1); | ||
337 | printk(KERN_NOTICE "PCI: updated MCFG configuration %d: base %lx " | ||
338 | "segment %hu buses %u - %u\n", | ||
339 | i, (unsigned long)cfg->address, cfg->pci_segment, | ||
340 | (unsigned int)cfg->start_bus_number, | ||
341 | (unsigned int)cfg->end_bus_number); | ||
342 | } | ||
343 | } | ||
344 | |||
345 | return valid; | ||
346 | } | ||
347 | |||
313 | static void __init pci_mmcfg_reject_broken(int early) | 348 | static void __init pci_mmcfg_reject_broken(int early) |
314 | { | 349 | { |
315 | typeof(pci_mmcfg_config[0]) *cfg; | 350 | typeof(pci_mmcfg_config[0]) *cfg; |
@@ -324,21 +359,22 @@ static void __init pci_mmcfg_reject_broken(int early) | |||
324 | 359 | ||
325 | for (i = 0; i < pci_mmcfg_config_num; i++) { | 360 | for (i = 0; i < pci_mmcfg_config_num; i++) { |
326 | int valid = 0; | 361 | int valid = 0; |
327 | u32 size = (cfg->end_bus_number + 1) << 20; | 362 | u64 addr, size; |
363 | |||
328 | cfg = &pci_mmcfg_config[i]; | 364 | cfg = &pci_mmcfg_config[i]; |
365 | addr = cfg->start_bus_number; | ||
366 | addr <<= 20; | ||
367 | addr += cfg->address; | ||
368 | size = cfg->end_bus_number + 1 - cfg->start_bus_number; | ||
369 | size <<= 20; | ||
329 | printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx " | 370 | printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx " |
330 | "segment %hu buses %u - %u\n", | 371 | "segment %hu buses %u - %u\n", |
331 | i, (unsigned long)cfg->address, cfg->pci_segment, | 372 | i, (unsigned long)cfg->address, cfg->pci_segment, |
332 | (unsigned int)cfg->start_bus_number, | 373 | (unsigned int)cfg->start_bus_number, |
333 | (unsigned int)cfg->end_bus_number); | 374 | (unsigned int)cfg->end_bus_number); |
334 | 375 | ||
335 | if (!early && | 376 | if (!early) |
336 | is_acpi_reserved(cfg->address, cfg->address + size - 1)) { | 377 | valid = is_mmconf_reserved(is_acpi_reserved, addr, size, i, cfg, 0); |
337 | printk(KERN_NOTICE "PCI: MCFG area at %Lx reserved " | ||
338 | "in ACPI motherboard resources\n", | ||
339 | cfg->address); | ||
340 | valid = 1; | ||
341 | } | ||
342 | 378 | ||
343 | if (valid) | 379 | if (valid) |
344 | continue; | 380 | continue; |
@@ -347,16 +383,11 @@ static void __init pci_mmcfg_reject_broken(int early) | |||
347 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not" | 383 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not" |
348 | " reserved in ACPI motherboard resources\n", | 384 | " reserved in ACPI motherboard resources\n", |
349 | cfg->address); | 385 | cfg->address); |
386 | |||
350 | /* Don't try to do this check unless configuration | 387 | /* Don't try to do this check unless configuration |
351 | type 1 is available. how about type 2 ?*/ | 388 | type 1 is available. how about type 2 ?*/ |
352 | if (raw_pci_ops && e820_all_mapped(cfg->address, | 389 | if (raw_pci_ops) |
353 | cfg->address + size - 1, | 390 | valid = is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1); |
354 | E820_RESERVED)) { | ||
355 | printk(KERN_NOTICE | ||
356 | "PCI: MCFG area at %Lx reserved in E820\n", | ||
357 | cfg->address); | ||
358 | valid = 1; | ||
359 | } | ||
360 | 391 | ||
361 | if (!valid) | 392 | if (!valid) |
362 | goto reject; | 393 | goto reject; |