diff options
Diffstat (limited to 'arch/i386')
34 files changed, 829 insertions, 326 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 8dfa3054f10f..1596101cfaf8 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -173,6 +173,12 @@ config ACPI_SRAT | |||
173 | bool | 173 | bool |
174 | default y | 174 | default y |
175 | depends on NUMA && (X86_SUMMIT || X86_GENERICARCH) | 175 | depends on NUMA && (X86_SUMMIT || X86_GENERICARCH) |
176 | select ACPI_NUMA | ||
177 | |||
178 | config HAVE_ARCH_PARSE_SRAT | ||
179 | bool | ||
180 | default y | ||
181 | depends on ACPI_SRAT | ||
176 | 182 | ||
177 | config X86_SUMMIT_NUMA | 183 | config X86_SUMMIT_NUMA |
178 | bool | 184 | bool |
@@ -224,7 +230,6 @@ config NR_CPUS | |||
224 | config SCHED_SMT | 230 | config SCHED_SMT |
225 | bool "SMT (Hyperthreading) scheduler support" | 231 | bool "SMT (Hyperthreading) scheduler support" |
226 | depends on SMP | 232 | depends on SMP |
227 | default off | ||
228 | help | 233 | help |
229 | SMT scheduler support improves the CPU scheduler's decision making | 234 | SMT scheduler support improves the CPU scheduler's decision making |
230 | when dealing with Intel Pentium 4 chips with HyperThreading at a | 235 | when dealing with Intel Pentium 4 chips with HyperThreading at a |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 40e5aba3ad3d..97ca17189af5 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -202,6 +202,8 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | |||
202 | if (mcfg->config[i].base_reserved) { | 202 | if (mcfg->config[i].base_reserved) { |
203 | printk(KERN_ERR PREFIX | 203 | printk(KERN_ERR PREFIX |
204 | "MMCONFIG not in low 4GB of memory\n"); | 204 | "MMCONFIG not in low 4GB of memory\n"); |
205 | kfree(pci_mmcfg_config); | ||
206 | pci_mmcfg_config_num = 0; | ||
205 | return -ENODEV; | 207 | return -ENODEV; |
206 | } | 208 | } |
207 | } | 209 | } |
@@ -215,7 +217,7 @@ static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) | |||
215 | { | 217 | { |
216 | struct acpi_table_madt *madt = NULL; | 218 | struct acpi_table_madt *madt = NULL; |
217 | 219 | ||
218 | if (!phys_addr || !size) | 220 | if (!phys_addr || !size || !cpu_has_apic) |
219 | return -EINVAL; | 221 | return -EINVAL; |
220 | 222 | ||
221 | madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); | 223 | madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); |
@@ -621,9 +623,9 @@ extern u32 pmtmr_ioport; | |||
621 | 623 | ||
622 | static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) | 624 | static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) |
623 | { | 625 | { |
624 | struct fadt_descriptor_rev2 *fadt = NULL; | 626 | struct fadt_descriptor *fadt = NULL; |
625 | 627 | ||
626 | fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size); | 628 | fadt = (struct fadt_descriptor *)__acpi_map_table(phys, size); |
627 | if (!fadt) { | 629 | if (!fadt) { |
628 | printk(KERN_WARNING PREFIX "Unable to map FADT\n"); | 630 | printk(KERN_WARNING PREFIX "Unable to map FADT\n"); |
629 | return 0; | 631 | return 0; |
@@ -754,7 +756,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) | |||
754 | return -ENODEV; | 756 | return -ENODEV; |
755 | } | 757 | } |
756 | 758 | ||
757 | if (!cpu_has_apic) | 759 | if (!cpu_has_apic) |
758 | return -ENODEV; | 760 | return -ENODEV; |
759 | 761 | ||
760 | /* | 762 | /* |
diff --git a/arch/i386/kernel/acpi/processor.c b/arch/i386/kernel/acpi/processor.c index 9f4cc02717ec..b54fded49834 100644 --- a/arch/i386/kernel/acpi/processor.c +++ b/arch/i386/kernel/acpi/processor.c | |||
@@ -47,7 +47,7 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) | |||
47 | buf[2] = ACPI_PDC_C_CAPABILITY_SMP; | 47 | buf[2] = ACPI_PDC_C_CAPABILITY_SMP; |
48 | 48 | ||
49 | if (cpu_has(c, X86_FEATURE_EST)) | 49 | if (cpu_has(c, X86_FEATURE_EST)) |
50 | buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; | 50 | buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP; |
51 | 51 | ||
52 | obj->type = ACPI_TYPE_BUFFER; | 52 | obj->type = ACPI_TYPE_BUFFER; |
53 | obj->buffer.length = 12; | 53 | obj->buffer.length = 12; |
diff --git a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c index 1cb2b186a3af..4ee83577bf61 100644 --- a/arch/i386/kernel/acpi/sleep.c +++ b/arch/i386/kernel/acpi/sleep.c | |||
@@ -8,30 +8,17 @@ | |||
8 | #include <linux/acpi.h> | 8 | #include <linux/acpi.h> |
9 | #include <linux/bootmem.h> | 9 | #include <linux/bootmem.h> |
10 | #include <linux/dmi.h> | 10 | #include <linux/dmi.h> |
11 | #include <linux/cpumask.h> | ||
12 | |||
11 | #include <asm/smp.h> | 13 | #include <asm/smp.h> |
12 | #include <asm/tlbflush.h> | ||
13 | 14 | ||
14 | /* address in low memory of the wakeup routine. */ | 15 | /* address in low memory of the wakeup routine. */ |
15 | unsigned long acpi_wakeup_address = 0; | 16 | unsigned long acpi_wakeup_address = 0; |
16 | unsigned long acpi_video_flags; | 17 | unsigned long acpi_video_flags; |
17 | extern char wakeup_start, wakeup_end; | 18 | extern char wakeup_start, wakeup_end; |
18 | 19 | ||
19 | extern void zap_low_mappings(void); | ||
20 | |||
21 | extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); | 20 | extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); |
22 | 21 | ||
23 | static void init_low_mapping(pgd_t * pgd, int pgd_limit) | ||
24 | { | ||
25 | int pgd_ofs = 0; | ||
26 | |||
27 | while ((pgd_ofs < pgd_limit) | ||
28 | && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) { | ||
29 | set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD)); | ||
30 | pgd_ofs++, pgd++; | ||
31 | } | ||
32 | flush_tlb_all(); | ||
33 | } | ||
34 | |||
35 | /** | 22 | /** |
36 | * acpi_save_state_mem - save kernel state | 23 | * acpi_save_state_mem - save kernel state |
37 | * | 24 | * |
@@ -42,7 +29,6 @@ int acpi_save_state_mem(void) | |||
42 | { | 29 | { |
43 | if (!acpi_wakeup_address) | 30 | if (!acpi_wakeup_address) |
44 | return 1; | 31 | return 1; |
45 | init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD); | ||
46 | memcpy((void *)acpi_wakeup_address, &wakeup_start, | 32 | memcpy((void *)acpi_wakeup_address, &wakeup_start, |
47 | &wakeup_end - &wakeup_start); | 33 | &wakeup_end - &wakeup_start); |
48 | acpi_copy_wakeup_routine(acpi_wakeup_address); | 34 | acpi_copy_wakeup_routine(acpi_wakeup_address); |
@@ -55,7 +41,6 @@ int acpi_save_state_mem(void) | |||
55 | */ | 41 | */ |
56 | void acpi_restore_state_mem(void) | 42 | void acpi_restore_state_mem(void) |
57 | { | 43 | { |
58 | zap_low_mappings(); | ||
59 | } | 44 | } |
60 | 45 | ||
61 | /** | 46 | /** |
diff --git a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S index 7c74fe0dc93c..9f408eee4e6f 100644 --- a/arch/i386/kernel/acpi/wakeup.S +++ b/arch/i386/kernel/acpi/wakeup.S | |||
@@ -56,7 +56,7 @@ wakeup_code: | |||
56 | 1: | 56 | 1: |
57 | 57 | ||
58 | # set up page table | 58 | # set up page table |
59 | movl $swapper_pg_dir-__PAGE_OFFSET, %eax | 59 | movl $swsusp_pg_dir-__PAGE_OFFSET, %eax |
60 | movl %eax, %cr3 | 60 | movl %eax, %cr3 |
61 | 61 | ||
62 | testl $1, real_efer_save_restore - wakeup_code | 62 | testl $1, real_efer_save_restore - wakeup_code |
@@ -265,11 +265,6 @@ ENTRY(acpi_copy_wakeup_routine) | |||
265 | movl $0x12345678, saved_magic | 265 | movl $0x12345678, saved_magic |
266 | ret | 266 | ret |
267 | 267 | ||
268 | .data | ||
269 | ALIGN | ||
270 | ENTRY(saved_magic) .long 0 | ||
271 | ENTRY(saved_eip) .long 0 | ||
272 | |||
273 | save_registers: | 268 | save_registers: |
274 | leal 4(%esp), %eax | 269 | leal 4(%esp), %eax |
275 | movl %eax, saved_context_esp | 270 | movl %eax, saved_context_esp |
@@ -304,7 +299,11 @@ ret_point: | |||
304 | call restore_processor_state | 299 | call restore_processor_state |
305 | ret | 300 | ret |
306 | 301 | ||
302 | .data | ||
307 | ALIGN | 303 | ALIGN |
304 | ENTRY(saved_magic) .long 0 | ||
305 | ENTRY(saved_eip) .long 0 | ||
306 | |||
308 | # saved registers | 307 | # saved registers |
309 | saved_gdt: .long 0,0 | 308 | saved_gdt: .long 0,0 |
310 | saved_idt: .long 0,0 | 309 | saved_idt: .long 0,0 |
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 3d4b2f3d116a..5ab59c12335b 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -62,7 +62,7 @@ int apic_verbosity; | |||
62 | 62 | ||
63 | static void apic_pm_activate(void); | 63 | static void apic_pm_activate(void); |
64 | 64 | ||
65 | int modern_apic(void) | 65 | static int modern_apic(void) |
66 | { | 66 | { |
67 | unsigned int lvr, version; | 67 | unsigned int lvr, version; |
68 | /* AMD systems use old APIC versions, so check the CPU */ | 68 | /* AMD systems use old APIC versions, so check the CPU */ |
@@ -113,7 +113,7 @@ void __init apic_intr_init(void) | |||
113 | } | 113 | } |
114 | 114 | ||
115 | /* Using APIC to generate smp_local_timer_interrupt? */ | 115 | /* Using APIC to generate smp_local_timer_interrupt? */ |
116 | int using_apic_timer = 0; | 116 | int using_apic_timer __read_mostly = 0; |
117 | 117 | ||
118 | static int enabled_via_apicbase; | 118 | static int enabled_via_apicbase; |
119 | 119 | ||
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index df0e1745f189..9e819eb68229 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c | |||
@@ -374,14 +374,14 @@ static struct { | |||
374 | unsigned short segment; | 374 | unsigned short segment; |
375 | } apm_bios_entry; | 375 | } apm_bios_entry; |
376 | static int clock_slowed; | 376 | static int clock_slowed; |
377 | static int idle_threshold = DEFAULT_IDLE_THRESHOLD; | 377 | static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD; |
378 | static int idle_period = DEFAULT_IDLE_PERIOD; | 378 | static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD; |
379 | static int set_pm_idle; | 379 | static int set_pm_idle; |
380 | static int suspends_pending; | 380 | static int suspends_pending; |
381 | static int standbys_pending; | 381 | static int standbys_pending; |
382 | static int ignore_sys_suspend; | 382 | static int ignore_sys_suspend; |
383 | static int ignore_normal_resume; | 383 | static int ignore_normal_resume; |
384 | static int bounce_interval = DEFAULT_BOUNCE_INTERVAL; | 384 | static int bounce_interval __read_mostly = DEFAULT_BOUNCE_INTERVAL; |
385 | 385 | ||
386 | #ifdef CONFIG_APM_RTC_IS_GMT | 386 | #ifdef CONFIG_APM_RTC_IS_GMT |
387 | # define clock_cmos_diff 0 | 387 | # define clock_cmos_diff 0 |
@@ -390,8 +390,8 @@ static int bounce_interval = DEFAULT_BOUNCE_INTERVAL; | |||
390 | static long clock_cmos_diff; | 390 | static long clock_cmos_diff; |
391 | static int got_clock_diff; | 391 | static int got_clock_diff; |
392 | #endif | 392 | #endif |
393 | static int debug; | 393 | static int debug __read_mostly; |
394 | static int smp; | 394 | static int smp __read_mostly; |
395 | static int apm_disabled = -1; | 395 | static int apm_disabled = -1; |
396 | #ifdef CONFIG_SMP | 396 | #ifdef CONFIG_SMP |
397 | static int power_off; | 397 | static int power_off; |
@@ -403,8 +403,8 @@ static int realmode_power_off = 1; | |||
403 | #else | 403 | #else |
404 | static int realmode_power_off; | 404 | static int realmode_power_off; |
405 | #endif | 405 | #endif |
406 | static int exit_kapmd; | 406 | static int exit_kapmd __read_mostly; |
407 | static int kapmd_running; | 407 | static int kapmd_running __read_mostly; |
408 | #ifdef CONFIG_APM_ALLOW_INTS | 408 | #ifdef CONFIG_APM_ALLOW_INTS |
409 | static int allow_ints = 1; | 409 | static int allow_ints = 1; |
410 | #else | 410 | #else |
@@ -416,15 +416,15 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); | |||
416 | static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); | 416 | static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); |
417 | static struct apm_user * user_list; | 417 | static struct apm_user * user_list; |
418 | static DEFINE_SPINLOCK(user_list_lock); | 418 | static DEFINE_SPINLOCK(user_list_lock); |
419 | static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; | 419 | static const struct desc_struct bad_bios_desc = { 0, 0x00409200 }; |
420 | 420 | ||
421 | static char driver_version[] = "1.16ac"; /* no spaces */ | 421 | static const char driver_version[] = "1.16ac"; /* no spaces */ |
422 | 422 | ||
423 | /* | 423 | /* |
424 | * APM event names taken from the APM 1.2 specification. These are | 424 | * APM event names taken from the APM 1.2 specification. These are |
425 | * the message codes that the BIOS uses to tell us about events | 425 | * the message codes that the BIOS uses to tell us about events |
426 | */ | 426 | */ |
427 | static char * apm_event_name[] = { | 427 | static const char * const apm_event_name[] = { |
428 | "system standby", | 428 | "system standby", |
429 | "system suspend", | 429 | "system suspend", |
430 | "normal resume", | 430 | "normal resume", |
@@ -616,7 +616,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in, | |||
616 | * @ecx_in: ECX register value for BIOS call | 616 | * @ecx_in: ECX register value for BIOS call |
617 | * @eax: EAX register on return from the BIOS call | 617 | * @eax: EAX register on return from the BIOS call |
618 | * | 618 | * |
619 | * Make a BIOS call that does only returns one value, or just status. | 619 | * Make a BIOS call that returns one value only, or just status. |
620 | * If there is an error, then the error code is returned in AH | 620 | * If there is an error, then the error code is returned in AH |
621 | * (bits 8-15 of eax) and this function returns non-zero. This is | 621 | * (bits 8-15 of eax) and this function returns non-zero. This is |
622 | * used for simpler BIOS operations. This call may hold interrupts | 622 | * used for simpler BIOS operations. This call may hold interrupts |
@@ -822,7 +822,7 @@ static void apm_do_busy(void) | |||
822 | #define IDLE_CALC_LIMIT (HZ * 100) | 822 | #define IDLE_CALC_LIMIT (HZ * 100) |
823 | #define IDLE_LEAKY_MAX 16 | 823 | #define IDLE_LEAKY_MAX 16 |
824 | 824 | ||
825 | static void (*original_pm_idle)(void); | 825 | static void (*original_pm_idle)(void) __read_mostly; |
826 | 826 | ||
827 | /** | 827 | /** |
828 | * apm_cpu_idle - cpu idling for APM capable Linux | 828 | * apm_cpu_idle - cpu idling for APM capable Linux |
@@ -1063,7 +1063,8 @@ static int apm_engage_power_management(u_short device, int enable) | |||
1063 | 1063 | ||
1064 | static int apm_console_blank(int blank) | 1064 | static int apm_console_blank(int blank) |
1065 | { | 1065 | { |
1066 | int error, i; | 1066 | int error = APM_NOT_ENGAGED; /* silence gcc */ |
1067 | int i; | ||
1067 | u_short state; | 1068 | u_short state; |
1068 | static const u_short dev[3] = { 0x100, 0x1FF, 0x101 }; | 1069 | static const u_short dev[3] = { 0x100, 0x1FF, 0x101 }; |
1069 | 1070 | ||
@@ -1104,7 +1105,8 @@ static int queue_empty(struct apm_user *as) | |||
1104 | 1105 | ||
1105 | static apm_event_t get_queued_event(struct apm_user *as) | 1106 | static apm_event_t get_queued_event(struct apm_user *as) |
1106 | { | 1107 | { |
1107 | as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; | 1108 | if (++as->event_tail >= APM_MAX_EVENTS) |
1109 | as->event_tail = 0; | ||
1108 | return as->events[as->event_tail]; | 1110 | return as->events[as->event_tail]; |
1109 | } | 1111 | } |
1110 | 1112 | ||
@@ -1118,13 +1120,16 @@ static void queue_event(apm_event_t event, struct apm_user *sender) | |||
1118 | for (as = user_list; as != NULL; as = as->next) { | 1120 | for (as = user_list; as != NULL; as = as->next) { |
1119 | if ((as == sender) || (!as->reader)) | 1121 | if ((as == sender) || (!as->reader)) |
1120 | continue; | 1122 | continue; |
1121 | as->event_head = (as->event_head + 1) % APM_MAX_EVENTS; | 1123 | if (++as->event_head >= APM_MAX_EVENTS) |
1124 | as->event_head = 0; | ||
1125 | |||
1122 | if (as->event_head == as->event_tail) { | 1126 | if (as->event_head == as->event_tail) { |
1123 | static int notified; | 1127 | static int notified; |
1124 | 1128 | ||
1125 | if (notified++ == 0) | 1129 | if (notified++ == 0) |
1126 | printk(KERN_ERR "apm: an event queue overflowed\n"); | 1130 | printk(KERN_ERR "apm: an event queue overflowed\n"); |
1127 | as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; | 1131 | if (++as->event_tail >= APM_MAX_EVENTS) |
1132 | as->event_tail = 0; | ||
1128 | } | 1133 | } |
1129 | as->events[as->event_head] = event; | 1134 | as->events[as->event_head] = event; |
1130 | if ((!as->suser) || (!as->writer)) | 1135 | if ((!as->suser) || (!as->writer)) |
@@ -1282,7 +1287,7 @@ static void standby(void) | |||
1282 | static apm_event_t get_event(void) | 1287 | static apm_event_t get_event(void) |
1283 | { | 1288 | { |
1284 | int error; | 1289 | int error; |
1285 | apm_event_t event; | 1290 | apm_event_t event = APM_NO_EVENTS; /* silence gcc */ |
1286 | apm_eventinfo_t info; | 1291 | apm_eventinfo_t info; |
1287 | 1292 | ||
1288 | static int notified; | 1293 | static int notified; |
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index a06a49075f10..44f2c5f2dda1 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <asm/msr.h> | 11 | #include <asm/msr.h> |
12 | #include <asm/io.h> | 12 | #include <asm/io.h> |
13 | #include <asm/mmu_context.h> | 13 | #include <asm/mmu_context.h> |
14 | #include <asm/mtrr.h> | ||
15 | #include <asm/mce.h> | ||
14 | #ifdef CONFIG_X86_LOCAL_APIC | 16 | #ifdef CONFIG_X86_LOCAL_APIC |
15 | #include <asm/mpspec.h> | 17 | #include <asm/mpspec.h> |
16 | #include <asm/apic.h> | 18 | #include <asm/apic.h> |
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 1a7bdcef1926..05668e3598c0 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -48,12 +48,13 @@ MODULE_LICENSE("GPL"); | |||
48 | 48 | ||
49 | 49 | ||
50 | struct cpufreq_acpi_io { | 50 | struct cpufreq_acpi_io { |
51 | struct acpi_processor_performance acpi_data; | 51 | struct acpi_processor_performance *acpi_data; |
52 | struct cpufreq_frequency_table *freq_table; | 52 | struct cpufreq_frequency_table *freq_table; |
53 | unsigned int resume; | 53 | unsigned int resume; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS]; | 56 | static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS]; |
57 | static struct acpi_processor_performance *acpi_perf_data[NR_CPUS]; | ||
57 | 58 | ||
58 | static struct cpufreq_driver acpi_cpufreq_driver; | 59 | static struct cpufreq_driver acpi_cpufreq_driver; |
59 | 60 | ||
@@ -104,64 +105,43 @@ acpi_processor_set_performance ( | |||
104 | { | 105 | { |
105 | u16 port = 0; | 106 | u16 port = 0; |
106 | u8 bit_width = 0; | 107 | u8 bit_width = 0; |
107 | int ret; | ||
108 | u32 value = 0; | ||
109 | int i = 0; | 108 | int i = 0; |
110 | struct cpufreq_freqs cpufreq_freqs; | 109 | int ret = 0; |
111 | cpumask_t saved_mask; | 110 | u32 value = 0; |
112 | int retval; | 111 | int retval; |
112 | struct acpi_processor_performance *perf; | ||
113 | 113 | ||
114 | dprintk("acpi_processor_set_performance\n"); | 114 | dprintk("acpi_processor_set_performance\n"); |
115 | 115 | ||
116 | /* | 116 | retval = 0; |
117 | * TBD: Use something other than set_cpus_allowed. | 117 | perf = data->acpi_data; |
118 | * As set_cpus_allowed is a bit racy, | 118 | if (state == perf->state) { |
119 | * with any other set_cpus_allowed for this process. | ||
120 | */ | ||
121 | saved_mask = current->cpus_allowed; | ||
122 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | ||
123 | if (smp_processor_id() != cpu) { | ||
124 | return (-EAGAIN); | ||
125 | } | ||
126 | |||
127 | if (state == data->acpi_data.state) { | ||
128 | if (unlikely(data->resume)) { | 119 | if (unlikely(data->resume)) { |
129 | dprintk("Called after resume, resetting to P%d\n", state); | 120 | dprintk("Called after resume, resetting to P%d\n", state); |
130 | data->resume = 0; | 121 | data->resume = 0; |
131 | } else { | 122 | } else { |
132 | dprintk("Already at target state (P%d)\n", state); | 123 | dprintk("Already at target state (P%d)\n", state); |
133 | retval = 0; | 124 | return (retval); |
134 | goto migrate_end; | ||
135 | } | 125 | } |
136 | } | 126 | } |
137 | 127 | ||
138 | dprintk("Transitioning from P%d to P%d\n", | 128 | dprintk("Transitioning from P%d to P%d\n", perf->state, state); |
139 | data->acpi_data.state, state); | ||
140 | |||
141 | /* cpufreq frequency struct */ | ||
142 | cpufreq_freqs.cpu = cpu; | ||
143 | cpufreq_freqs.old = data->freq_table[data->acpi_data.state].frequency; | ||
144 | cpufreq_freqs.new = data->freq_table[state].frequency; | ||
145 | |||
146 | /* notify cpufreq */ | ||
147 | cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); | ||
148 | 129 | ||
149 | /* | 130 | /* |
150 | * First we write the target state's 'control' value to the | 131 | * First we write the target state's 'control' value to the |
151 | * control_register. | 132 | * control_register. |
152 | */ | 133 | */ |
153 | 134 | ||
154 | port = data->acpi_data.control_register.address; | 135 | port = perf->control_register.address; |
155 | bit_width = data->acpi_data.control_register.bit_width; | 136 | bit_width = perf->control_register.bit_width; |
156 | value = (u32) data->acpi_data.states[state].control; | 137 | value = (u32) perf->states[state].control; |
157 | 138 | ||
158 | dprintk("Writing 0x%08x to port 0x%04x\n", value, port); | 139 | dprintk("Writing 0x%08x to port 0x%04x\n", value, port); |
159 | 140 | ||
160 | ret = acpi_processor_write_port(port, bit_width, value); | 141 | ret = acpi_processor_write_port(port, bit_width, value); |
161 | if (ret) { | 142 | if (ret) { |
162 | dprintk("Invalid port width 0x%04x\n", bit_width); | 143 | dprintk("Invalid port width 0x%04x\n", bit_width); |
163 | retval = ret; | 144 | return (ret); |
164 | goto migrate_end; | ||
165 | } | 145 | } |
166 | 146 | ||
167 | /* | 147 | /* |
@@ -177,48 +157,35 @@ acpi_processor_set_performance ( | |||
177 | * before giving up. | 157 | * before giving up. |
178 | */ | 158 | */ |
179 | 159 | ||
180 | port = data->acpi_data.status_register.address; | 160 | port = perf->status_register.address; |
181 | bit_width = data->acpi_data.status_register.bit_width; | 161 | bit_width = perf->status_register.bit_width; |
182 | 162 | ||
183 | dprintk("Looking for 0x%08x from port 0x%04x\n", | 163 | dprintk("Looking for 0x%08x from port 0x%04x\n", |
184 | (u32) data->acpi_data.states[state].status, port); | 164 | (u32) perf->states[state].status, port); |
185 | 165 | ||
186 | for (i=0; i<100; i++) { | 166 | for (i = 0; i < 100; i++) { |
187 | ret = acpi_processor_read_port(port, bit_width, &value); | 167 | ret = acpi_processor_read_port(port, bit_width, &value); |
188 | if (ret) { | 168 | if (ret) { |
189 | dprintk("Invalid port width 0x%04x\n", bit_width); | 169 | dprintk("Invalid port width 0x%04x\n", bit_width); |
190 | retval = ret; | 170 | return (ret); |
191 | goto migrate_end; | ||
192 | } | 171 | } |
193 | if (value == (u32) data->acpi_data.states[state].status) | 172 | if (value == (u32) perf->states[state].status) |
194 | break; | 173 | break; |
195 | udelay(10); | 174 | udelay(10); |
196 | } | 175 | } |
197 | } else { | 176 | } else { |
198 | value = (u32) data->acpi_data.states[state].status; | 177 | value = (u32) perf->states[state].status; |
199 | } | 178 | } |
200 | 179 | ||
201 | /* notify cpufreq */ | 180 | if (unlikely(value != (u32) perf->states[state].status)) { |
202 | cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); | ||
203 | |||
204 | if (unlikely(value != (u32) data->acpi_data.states[state].status)) { | ||
205 | unsigned int tmp = cpufreq_freqs.new; | ||
206 | cpufreq_freqs.new = cpufreq_freqs.old; | ||
207 | cpufreq_freqs.old = tmp; | ||
208 | cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); | ||
209 | cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); | ||
210 | printk(KERN_WARNING "acpi-cpufreq: Transition failed\n"); | 181 | printk(KERN_WARNING "acpi-cpufreq: Transition failed\n"); |
211 | retval = -ENODEV; | 182 | retval = -ENODEV; |
212 | goto migrate_end; | 183 | return (retval); |
213 | } | 184 | } |
214 | 185 | ||
215 | dprintk("Transition successful after %d microseconds\n", i * 10); | 186 | dprintk("Transition successful after %d microseconds\n", i * 10); |
216 | 187 | ||
217 | data->acpi_data.state = state; | 188 | perf->state = state; |
218 | |||
219 | retval = 0; | ||
220 | migrate_end: | ||
221 | set_cpus_allowed(current, saved_mask); | ||
222 | return (retval); | 189 | return (retval); |
223 | } | 190 | } |
224 | 191 | ||
@@ -230,8 +197,17 @@ acpi_cpufreq_target ( | |||
230 | unsigned int relation) | 197 | unsigned int relation) |
231 | { | 198 | { |
232 | struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; | 199 | struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; |
200 | struct acpi_processor_performance *perf; | ||
201 | struct cpufreq_freqs freqs; | ||
202 | cpumask_t online_policy_cpus; | ||
203 | cpumask_t saved_mask; | ||
204 | cpumask_t set_mask; | ||
205 | cpumask_t covered_cpus; | ||
206 | unsigned int cur_state = 0; | ||
233 | unsigned int next_state = 0; | 207 | unsigned int next_state = 0; |
234 | unsigned int result = 0; | 208 | unsigned int result = 0; |
209 | unsigned int j; | ||
210 | unsigned int tmp; | ||
235 | 211 | ||
236 | dprintk("acpi_cpufreq_setpolicy\n"); | 212 | dprintk("acpi_cpufreq_setpolicy\n"); |
237 | 213 | ||
@@ -240,11 +216,95 @@ acpi_cpufreq_target ( | |||
240 | target_freq, | 216 | target_freq, |
241 | relation, | 217 | relation, |
242 | &next_state); | 218 | &next_state); |
243 | if (result) | 219 | if (unlikely(result)) |
244 | return (result); | 220 | return (result); |
245 | 221 | ||
246 | result = acpi_processor_set_performance (data, policy->cpu, next_state); | 222 | perf = data->acpi_data; |
223 | cur_state = perf->state; | ||
224 | freqs.old = data->freq_table[cur_state].frequency; | ||
225 | freqs.new = data->freq_table[next_state].frequency; | ||
226 | |||
227 | #ifdef CONFIG_HOTPLUG_CPU | ||
228 | /* cpufreq holds the hotplug lock, so we are safe from here on */ | ||
229 | cpus_and(online_policy_cpus, cpu_online_map, policy->cpus); | ||
230 | #else | ||
231 | online_policy_cpus = policy->cpus; | ||
232 | #endif | ||
233 | |||
234 | for_each_cpu_mask(j, online_policy_cpus) { | ||
235 | freqs.cpu = j; | ||
236 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
237 | } | ||
238 | |||
239 | /* | ||
240 | * We need to call driver->target() on all or any CPU in | ||
241 | * policy->cpus, depending on policy->shared_type. | ||
242 | */ | ||
243 | saved_mask = current->cpus_allowed; | ||
244 | cpus_clear(covered_cpus); | ||
245 | for_each_cpu_mask(j, online_policy_cpus) { | ||
246 | /* | ||
247 | * Support for SMP systems. | ||
248 | * Make sure we are running on CPU that wants to change freq | ||
249 | */ | ||
250 | cpus_clear(set_mask); | ||
251 | if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) | ||
252 | cpus_or(set_mask, set_mask, online_policy_cpus); | ||
253 | else | ||
254 | cpu_set(j, set_mask); | ||
255 | |||
256 | set_cpus_allowed(current, set_mask); | ||
257 | if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) { | ||
258 | dprintk("couldn't limit to CPUs in this domain\n"); | ||
259 | result = -EAGAIN; | ||
260 | break; | ||
261 | } | ||
262 | |||
263 | result = acpi_processor_set_performance (data, j, next_state); | ||
264 | if (result) { | ||
265 | result = -EAGAIN; | ||
266 | break; | ||
267 | } | ||
268 | |||
269 | if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) | ||
270 | break; | ||
271 | |||
272 | cpu_set(j, covered_cpus); | ||
273 | } | ||
274 | |||
275 | for_each_cpu_mask(j, online_policy_cpus) { | ||
276 | freqs.cpu = j; | ||
277 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
278 | } | ||
247 | 279 | ||
280 | if (unlikely(result)) { | ||
281 | /* | ||
282 | * We have failed halfway through the frequency change. | ||
283 | * We have sent callbacks to online_policy_cpus and | ||
284 | * acpi_processor_set_performance() has been called on | ||
285 | * coverd_cpus. Best effort undo.. | ||
286 | */ | ||
287 | |||
288 | if (!cpus_empty(covered_cpus)) { | ||
289 | for_each_cpu_mask(j, covered_cpus) { | ||
290 | policy->cpu = j; | ||
291 | acpi_processor_set_performance (data, | ||
292 | j, | ||
293 | cur_state); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | tmp = freqs.new; | ||
298 | freqs.new = freqs.old; | ||
299 | freqs.old = tmp; | ||
300 | for_each_cpu_mask(j, online_policy_cpus) { | ||
301 | freqs.cpu = j; | ||
302 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
303 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
304 | } | ||
305 | } | ||
306 | |||
307 | set_cpus_allowed(current, saved_mask); | ||
248 | return (result); | 308 | return (result); |
249 | } | 309 | } |
250 | 310 | ||
@@ -270,30 +330,65 @@ acpi_cpufreq_guess_freq ( | |||
270 | struct cpufreq_acpi_io *data, | 330 | struct cpufreq_acpi_io *data, |
271 | unsigned int cpu) | 331 | unsigned int cpu) |
272 | { | 332 | { |
333 | struct acpi_processor_performance *perf = data->acpi_data; | ||
334 | |||
273 | if (cpu_khz) { | 335 | if (cpu_khz) { |
274 | /* search the closest match to cpu_khz */ | 336 | /* search the closest match to cpu_khz */ |
275 | unsigned int i; | 337 | unsigned int i; |
276 | unsigned long freq; | 338 | unsigned long freq; |
277 | unsigned long freqn = data->acpi_data.states[0].core_frequency * 1000; | 339 | unsigned long freqn = perf->states[0].core_frequency * 1000; |
278 | 340 | ||
279 | for (i=0; i < (data->acpi_data.state_count - 1); i++) { | 341 | for (i = 0; i < (perf->state_count - 1); i++) { |
280 | freq = freqn; | 342 | freq = freqn; |
281 | freqn = data->acpi_data.states[i+1].core_frequency * 1000; | 343 | freqn = perf->states[i+1].core_frequency * 1000; |
282 | if ((2 * cpu_khz) > (freqn + freq)) { | 344 | if ((2 * cpu_khz) > (freqn + freq)) { |
283 | data->acpi_data.state = i; | 345 | perf->state = i; |
284 | return (freq); | 346 | return (freq); |
285 | } | 347 | } |
286 | } | 348 | } |
287 | data->acpi_data.state = data->acpi_data.state_count - 1; | 349 | perf->state = perf->state_count - 1; |
288 | return (freqn); | 350 | return (freqn); |
289 | } else | 351 | } else { |
290 | /* assume CPU is at P0... */ | 352 | /* assume CPU is at P0... */ |
291 | data->acpi_data.state = 0; | 353 | perf->state = 0; |
292 | return data->acpi_data.states[0].core_frequency * 1000; | 354 | return perf->states[0].core_frequency * 1000; |
293 | 355 | } | |
294 | } | 356 | } |
295 | 357 | ||
296 | 358 | ||
359 | /* | ||
360 | * acpi_cpufreq_early_init - initialize ACPI P-States library | ||
361 | * | ||
362 | * Initialize the ACPI P-States library (drivers/acpi/processor_perflib.c) | ||
363 | * in order to determine correct frequency and voltage pairings. We can | ||
364 | * do _PDC and _PSD and find out the processor dependency for the | ||
365 | * actual init that will happen later... | ||
366 | */ | ||
367 | static int acpi_cpufreq_early_init_acpi(void) | ||
368 | { | ||
369 | struct acpi_processor_performance *data; | ||
370 | unsigned int i, j; | ||
371 | |||
372 | dprintk("acpi_cpufreq_early_init\n"); | ||
373 | |||
374 | for_each_cpu(i) { | ||
375 | data = kzalloc(sizeof(struct acpi_processor_performance), | ||
376 | GFP_KERNEL); | ||
377 | if (!data) { | ||
378 | for_each_cpu(j) { | ||
379 | kfree(acpi_perf_data[j]); | ||
380 | acpi_perf_data[j] = NULL; | ||
381 | } | ||
382 | return (-ENOMEM); | ||
383 | } | ||
384 | acpi_perf_data[i] = data; | ||
385 | } | ||
386 | |||
387 | /* Do initialization in ACPI core */ | ||
388 | acpi_processor_preregister_performance(acpi_perf_data); | ||
389 | return 0; | ||
390 | } | ||
391 | |||
297 | static int | 392 | static int |
298 | acpi_cpufreq_cpu_init ( | 393 | acpi_cpufreq_cpu_init ( |
299 | struct cpufreq_policy *policy) | 394 | struct cpufreq_policy *policy) |
@@ -303,41 +398,51 @@ acpi_cpufreq_cpu_init ( | |||
303 | struct cpufreq_acpi_io *data; | 398 | struct cpufreq_acpi_io *data; |
304 | unsigned int result = 0; | 399 | unsigned int result = 0; |
305 | struct cpuinfo_x86 *c = &cpu_data[policy->cpu]; | 400 | struct cpuinfo_x86 *c = &cpu_data[policy->cpu]; |
401 | struct acpi_processor_performance *perf; | ||
306 | 402 | ||
307 | dprintk("acpi_cpufreq_cpu_init\n"); | 403 | dprintk("acpi_cpufreq_cpu_init\n"); |
308 | 404 | ||
405 | if (!acpi_perf_data[cpu]) | ||
406 | return (-ENODEV); | ||
407 | |||
309 | data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); | 408 | data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); |
310 | if (!data) | 409 | if (!data) |
311 | return (-ENOMEM); | 410 | return (-ENOMEM); |
312 | 411 | ||
412 | data->acpi_data = acpi_perf_data[cpu]; | ||
313 | acpi_io_data[cpu] = data; | 413 | acpi_io_data[cpu] = data; |
314 | 414 | ||
315 | result = acpi_processor_register_performance(&data->acpi_data, cpu); | 415 | result = acpi_processor_register_performance(data->acpi_data, cpu); |
316 | 416 | ||
317 | if (result) | 417 | if (result) |
318 | goto err_free; | 418 | goto err_free; |
319 | 419 | ||
420 | perf = data->acpi_data; | ||
421 | policy->cpus = perf->shared_cpu_map; | ||
422 | policy->shared_type = perf->shared_type; | ||
423 | |||
320 | if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { | 424 | if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { |
321 | acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; | 425 | acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; |
322 | } | 426 | } |
323 | 427 | ||
324 | /* capability check */ | 428 | /* capability check */ |
325 | if (data->acpi_data.state_count <= 1) { | 429 | if (perf->state_count <= 1) { |
326 | dprintk("No P-States\n"); | 430 | dprintk("No P-States\n"); |
327 | result = -ENODEV; | 431 | result = -ENODEV; |
328 | goto err_unreg; | 432 | goto err_unreg; |
329 | } | 433 | } |
330 | if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO) || | 434 | |
331 | (data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { | 435 | if ((perf->control_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO) || |
436 | (perf->status_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { | ||
332 | dprintk("Unsupported address space [%d, %d]\n", | 437 | dprintk("Unsupported address space [%d, %d]\n", |
333 | (u32) (data->acpi_data.control_register.space_id), | 438 | (u32) (perf->control_register.space_id), |
334 | (u32) (data->acpi_data.status_register.space_id)); | 439 | (u32) (perf->status_register.space_id)); |
335 | result = -ENODEV; | 440 | result = -ENODEV; |
336 | goto err_unreg; | 441 | goto err_unreg; |
337 | } | 442 | } |
338 | 443 | ||
339 | /* alloc freq_table */ | 444 | /* alloc freq_table */ |
340 | data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * (data->acpi_data.state_count + 1), GFP_KERNEL); | 445 | data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * (perf->state_count + 1), GFP_KERNEL); |
341 | if (!data->freq_table) { | 446 | if (!data->freq_table) { |
342 | result = -ENOMEM; | 447 | result = -ENOMEM; |
343 | goto err_unreg; | 448 | goto err_unreg; |
@@ -345,9 +450,9 @@ acpi_cpufreq_cpu_init ( | |||
345 | 450 | ||
346 | /* detect transition latency */ | 451 | /* detect transition latency */ |
347 | policy->cpuinfo.transition_latency = 0; | 452 | policy->cpuinfo.transition_latency = 0; |
348 | for (i=0; i<data->acpi_data.state_count; i++) { | 453 | for (i=0; i<perf->state_count; i++) { |
349 | if ((data->acpi_data.states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency) | 454 | if ((perf->states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency) |
350 | policy->cpuinfo.transition_latency = data->acpi_data.states[i].transition_latency * 1000; | 455 | policy->cpuinfo.transition_latency = perf->states[i].transition_latency * 1000; |
351 | } | 456 | } |
352 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | 457 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; |
353 | 458 | ||
@@ -355,11 +460,11 @@ acpi_cpufreq_cpu_init ( | |||
355 | policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); | 460 | policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); |
356 | 461 | ||
357 | /* table init */ | 462 | /* table init */ |
358 | for (i=0; i<=data->acpi_data.state_count; i++) | 463 | for (i=0; i<=perf->state_count; i++) |
359 | { | 464 | { |
360 | data->freq_table[i].index = i; | 465 | data->freq_table[i].index = i; |
361 | if (i<data->acpi_data.state_count) | 466 | if (i<perf->state_count) |
362 | data->freq_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000; | 467 | data->freq_table[i].frequency = perf->states[i].core_frequency * 1000; |
363 | else | 468 | else |
364 | data->freq_table[i].frequency = CPUFREQ_TABLE_END; | 469 | data->freq_table[i].frequency = CPUFREQ_TABLE_END; |
365 | } | 470 | } |
@@ -374,12 +479,12 @@ acpi_cpufreq_cpu_init ( | |||
374 | 479 | ||
375 | printk(KERN_INFO "acpi-cpufreq: CPU%u - ACPI performance management activated.\n", | 480 | printk(KERN_INFO "acpi-cpufreq: CPU%u - ACPI performance management activated.\n", |
376 | cpu); | 481 | cpu); |
377 | for (i = 0; i < data->acpi_data.state_count; i++) | 482 | for (i = 0; i < perf->state_count; i++) |
378 | dprintk(" %cP%d: %d MHz, %d mW, %d uS\n", | 483 | dprintk(" %cP%d: %d MHz, %d mW, %d uS\n", |
379 | (i == data->acpi_data.state?'*':' '), i, | 484 | (i == perf->state?'*':' '), i, |
380 | (u32) data->acpi_data.states[i].core_frequency, | 485 | (u32) perf->states[i].core_frequency, |
381 | (u32) data->acpi_data.states[i].power, | 486 | (u32) perf->states[i].power, |
382 | (u32) data->acpi_data.states[i].transition_latency); | 487 | (u32) perf->states[i].transition_latency); |
383 | 488 | ||
384 | cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu); | 489 | cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu); |
385 | 490 | ||
@@ -394,7 +499,7 @@ acpi_cpufreq_cpu_init ( | |||
394 | err_freqfree: | 499 | err_freqfree: |
395 | kfree(data->freq_table); | 500 | kfree(data->freq_table); |
396 | err_unreg: | 501 | err_unreg: |
397 | acpi_processor_unregister_performance(&data->acpi_data, cpu); | 502 | acpi_processor_unregister_performance(perf, cpu); |
398 | err_free: | 503 | err_free: |
399 | kfree(data); | 504 | kfree(data); |
400 | acpi_io_data[cpu] = NULL; | 505 | acpi_io_data[cpu] = NULL; |
@@ -415,7 +520,7 @@ acpi_cpufreq_cpu_exit ( | |||
415 | if (data) { | 520 | if (data) { |
416 | cpufreq_frequency_table_put_attr(policy->cpu); | 521 | cpufreq_frequency_table_put_attr(policy->cpu); |
417 | acpi_io_data[policy->cpu] = NULL; | 522 | acpi_io_data[policy->cpu] = NULL; |
418 | acpi_processor_unregister_performance(&data->acpi_data, policy->cpu); | 523 | acpi_processor_unregister_performance(data->acpi_data, policy->cpu); |
419 | kfree(data); | 524 | kfree(data); |
420 | } | 525 | } |
421 | 526 | ||
@@ -462,7 +567,10 @@ acpi_cpufreq_init (void) | |||
462 | 567 | ||
463 | dprintk("acpi_cpufreq_init\n"); | 568 | dprintk("acpi_cpufreq_init\n"); |
464 | 569 | ||
465 | result = cpufreq_register_driver(&acpi_cpufreq_driver); | 570 | result = acpi_cpufreq_early_init_acpi(); |
571 | |||
572 | if (!result) | ||
573 | result = cpufreq_register_driver(&acpi_cpufreq_driver); | ||
466 | 574 | ||
467 | return (result); | 575 | return (result); |
468 | } | 576 | } |
@@ -471,10 +579,15 @@ acpi_cpufreq_init (void) | |||
471 | static void __exit | 579 | static void __exit |
472 | acpi_cpufreq_exit (void) | 580 | acpi_cpufreq_exit (void) |
473 | { | 581 | { |
582 | unsigned int i; | ||
474 | dprintk("acpi_cpufreq_exit\n"); | 583 | dprintk("acpi_cpufreq_exit\n"); |
475 | 584 | ||
476 | cpufreq_unregister_driver(&acpi_cpufreq_driver); | 585 | cpufreq_unregister_driver(&acpi_cpufreq_driver); |
477 | 586 | ||
587 | for_each_cpu(i) { | ||
588 | kfree(acpi_perf_data[i]); | ||
589 | acpi_perf_data[i] = NULL; | ||
590 | } | ||
478 | return; | 591 | return; |
479 | } | 592 | } |
480 | 593 | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index b4277f58f40c..2d6491672559 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -120,7 +120,7 @@ static int pending_bit_stuck(void) | |||
120 | { | 120 | { |
121 | u32 lo, hi; | 121 | u32 lo, hi; |
122 | 122 | ||
123 | if (cpu_family) | 123 | if (cpu_family == CPU_HW_PSTATE) |
124 | return 0; | 124 | return 0; |
125 | 125 | ||
126 | rdmsr(MSR_FIDVID_STATUS, lo, hi); | 126 | rdmsr(MSR_FIDVID_STATUS, lo, hi); |
@@ -136,7 +136,7 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data) | |||
136 | u32 lo, hi; | 136 | u32 lo, hi; |
137 | u32 i = 0; | 137 | u32 i = 0; |
138 | 138 | ||
139 | if (cpu_family) { | 139 | if (cpu_family == CPU_HW_PSTATE) { |
140 | rdmsr(MSR_PSTATE_STATUS, lo, hi); | 140 | rdmsr(MSR_PSTATE_STATUS, lo, hi); |
141 | i = lo & HW_PSTATE_MASK; | 141 | i = lo & HW_PSTATE_MASK; |
142 | rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi); | 142 | rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi); |
@@ -598,7 +598,7 @@ static void print_basics(struct powernow_k8_data *data) | |||
598 | int j; | 598 | int j; |
599 | for (j = 0; j < data->numps; j++) { | 599 | for (j = 0; j < data->numps; j++) { |
600 | if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) { | 600 | if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) { |
601 | if (cpu_family) { | 601 | if (cpu_family == CPU_HW_PSTATE) { |
602 | printk(KERN_INFO PFX " %d : fid 0x%x gid 0x%x (%d MHz)\n", j, (data->powernow_table[j].index & 0xff00) >> 8, | 602 | printk(KERN_INFO PFX " %d : fid 0x%x gid 0x%x (%d MHz)\n", j, (data->powernow_table[j].index & 0xff00) >> 8, |
603 | (data->powernow_table[j].index & 0xff0000) >> 16, | 603 | (data->powernow_table[j].index & 0xff0000) >> 16, |
604 | data->powernow_table[j].frequency/1000); | 604 | data->powernow_table[j].frequency/1000); |
@@ -758,7 +758,7 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
758 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI | 758 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI |
759 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) | 759 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) |
760 | { | 760 | { |
761 | if (!data->acpi_data.state_count || cpu_family) | 761 | if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) |
762 | return; | 762 | return; |
763 | 763 | ||
764 | data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; | 764 | data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; |
@@ -801,7 +801,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
801 | goto err_out; | 801 | goto err_out; |
802 | } | 802 | } |
803 | 803 | ||
804 | if (cpu_family) | 804 | if (cpu_family == CPU_HW_PSTATE) |
805 | ret_val = fill_powernow_table_pstate(data, powernow_table); | 805 | ret_val = fill_powernow_table_pstate(data, powernow_table); |
806 | else | 806 | else |
807 | ret_val = fill_powernow_table_fidvid(data, powernow_table); | 807 | ret_val = fill_powernow_table_fidvid(data, powernow_table); |
@@ -885,8 +885,8 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf | |||
885 | u32 vid; | 885 | u32 vid; |
886 | 886 | ||
887 | if (data->exttype) { | 887 | if (data->exttype) { |
888 | fid = data->acpi_data.states[i].status & FID_MASK; | 888 | fid = data->acpi_data.states[i].status & EXT_FID_MASK; |
889 | vid = (data->acpi_data.states[i].status >> VID_SHIFT) & VID_MASK; | 889 | vid = (data->acpi_data.states[i].status >> VID_SHIFT) & EXT_VID_MASK; |
890 | } else { | 890 | } else { |
891 | fid = data->acpi_data.states[i].control & FID_MASK; | 891 | fid = data->acpi_data.states[i].control & FID_MASK; |
892 | vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; | 892 | vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; |
@@ -1082,7 +1082,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
1082 | if (query_current_values_with_pending_wait(data)) | 1082 | if (query_current_values_with_pending_wait(data)) |
1083 | goto err_out; | 1083 | goto err_out; |
1084 | 1084 | ||
1085 | if (cpu_family) | 1085 | if (cpu_family == CPU_HW_PSTATE) |
1086 | dprintk("targ: curr fid 0x%x, did 0x%x\n", | 1086 | dprintk("targ: curr fid 0x%x, did 0x%x\n", |
1087 | data->currfid, data->currvid); | 1087 | data->currfid, data->currvid); |
1088 | else { | 1088 | else { |
@@ -1103,7 +1103,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
1103 | 1103 | ||
1104 | powernow_k8_acpi_pst_values(data, newstate); | 1104 | powernow_k8_acpi_pst_values(data, newstate); |
1105 | 1105 | ||
1106 | if (cpu_family) | 1106 | if (cpu_family == CPU_HW_PSTATE) |
1107 | ret = transition_frequency_pstate(data, newstate); | 1107 | ret = transition_frequency_pstate(data, newstate); |
1108 | else | 1108 | else |
1109 | ret = transition_frequency_fidvid(data, newstate); | 1109 | ret = transition_frequency_fidvid(data, newstate); |
@@ -1115,7 +1115,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
1115 | } | 1115 | } |
1116 | mutex_unlock(&fidvid_mutex); | 1116 | mutex_unlock(&fidvid_mutex); |
1117 | 1117 | ||
1118 | if (cpu_family) | 1118 | if (cpu_family == CPU_HW_PSTATE) |
1119 | pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); | 1119 | pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); |
1120 | else | 1120 | else |
1121 | pol->cur = find_khz_freq_from_fid(data->currfid); | 1121 | pol->cur = find_khz_freq_from_fid(data->currfid); |
@@ -1163,7 +1163,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1163 | * Use the PSB BIOS structure. This is only availabe on | 1163 | * Use the PSB BIOS structure. This is only availabe on |
1164 | * an UP version, and is deprecated by AMD. | 1164 | * an UP version, and is deprecated by AMD. |
1165 | */ | 1165 | */ |
1166 | if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { | 1166 | if (num_online_cpus() != 1) { |
1167 | printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); | 1167 | printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); |
1168 | kfree(data); | 1168 | kfree(data); |
1169 | return -ENODEV; | 1169 | return -ENODEV; |
@@ -1197,14 +1197,14 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1197 | if (query_current_values_with_pending_wait(data)) | 1197 | if (query_current_values_with_pending_wait(data)) |
1198 | goto err_out; | 1198 | goto err_out; |
1199 | 1199 | ||
1200 | if (!cpu_family) | 1200 | if (cpu_family == CPU_OPTERON) |
1201 | fidvid_msr_init(); | 1201 | fidvid_msr_init(); |
1202 | 1202 | ||
1203 | /* run on any CPU again */ | 1203 | /* run on any CPU again */ |
1204 | set_cpus_allowed(current, oldmask); | 1204 | set_cpus_allowed(current, oldmask); |
1205 | 1205 | ||
1206 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; | 1206 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; |
1207 | if (cpu_family) | 1207 | if (cpu_family == CPU_HW_PSTATE) |
1208 | pol->cpus = cpumask_of_cpu(pol->cpu); | 1208 | pol->cpus = cpumask_of_cpu(pol->cpu); |
1209 | else | 1209 | else |
1210 | pol->cpus = cpu_core_map[pol->cpu]; | 1210 | pol->cpus = cpu_core_map[pol->cpu]; |
@@ -1215,7 +1215,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1215 | pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) | 1215 | pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) |
1216 | + (3 * (1 << data->irt) * 10)) * 1000; | 1216 | + (3 * (1 << data->irt) * 10)) * 1000; |
1217 | 1217 | ||
1218 | if (cpu_family) | 1218 | if (cpu_family == CPU_HW_PSTATE) |
1219 | pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); | 1219 | pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); |
1220 | else | 1220 | else |
1221 | pol->cur = find_khz_freq_from_fid(data->currfid); | 1221 | pol->cur = find_khz_freq_from_fid(data->currfid); |
@@ -1232,7 +1232,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1232 | 1232 | ||
1233 | cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); | 1233 | cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); |
1234 | 1234 | ||
1235 | if (cpu_family) | 1235 | if (cpu_family == CPU_HW_PSTATE) |
1236 | dprintk("cpu_init done, current fid 0x%x, did 0x%x\n", | 1236 | dprintk("cpu_init done, current fid 0x%x, did 0x%x\n", |
1237 | data->currfid, data->currdid); | 1237 | data->currfid, data->currdid); |
1238 | else | 1238 | else |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index bf8ad9e43da3..0fb2a3001ba5 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h | |||
@@ -169,7 +169,9 @@ struct powernow_k8_data { | |||
169 | #define MVS_MASK 3 | 169 | #define MVS_MASK 3 |
170 | #define VST_MASK 0x7f | 170 | #define VST_MASK 0x7f |
171 | #define VID_MASK 0x1f | 171 | #define VID_MASK 0x1f |
172 | #define FID_MASK 0x3f | 172 | #define FID_MASK 0x1f |
173 | #define EXT_VID_MASK 0x3f | ||
174 | #define EXT_FID_MASK 0x3f | ||
173 | 175 | ||
174 | 176 | ||
175 | /* | 177 | /* |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index ce54ff12c15d..31c3a5baaa7f 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | |||
@@ -2,19 +2,15 @@ | |||
2 | * cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium | 2 | * cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium |
3 | * M (part of the Centrino chipset). | 3 | * M (part of the Centrino chipset). |
4 | * | 4 | * |
5 | * Since the original Pentium M, most new Intel CPUs support Enhanced | ||
6 | * SpeedStep. | ||
7 | * | ||
5 | * Despite the "SpeedStep" in the name, this is almost entirely unlike | 8 | * Despite the "SpeedStep" in the name, this is almost entirely unlike |
6 | * traditional SpeedStep. | 9 | * traditional SpeedStep. |
7 | * | 10 | * |
8 | * Modelled on speedstep.c | 11 | * Modelled on speedstep.c |
9 | * | 12 | * |
10 | * Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org> | 13 | * Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org> |
11 | * | ||
12 | * WARNING WARNING WARNING | ||
13 | * | ||
14 | * This driver manipulates the PERF_CTL MSR, which is only somewhat | ||
15 | * documented. While it seems to work on my laptop, it has not been | ||
16 | * tested anywhere else, and it may not work for you, do strange | ||
17 | * things or simply crash. | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
@@ -36,7 +32,7 @@ | |||
36 | #include <asm/cpufeature.h> | 32 | #include <asm/cpufeature.h> |
37 | 33 | ||
38 | #define PFX "speedstep-centrino: " | 34 | #define PFX "speedstep-centrino: " |
39 | #define MAINTAINER "Jeremy Fitzhardinge <jeremy@goop.org>" | 35 | #define MAINTAINER "cpufreq@lists.linux.org.uk" |
40 | 36 | ||
41 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg) | 37 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg) |
42 | 38 | ||
@@ -351,7 +347,36 @@ static unsigned int get_cur_freq(unsigned int cpu) | |||
351 | 347 | ||
352 | #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI | 348 | #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI |
353 | 349 | ||
354 | static struct acpi_processor_performance p; | 350 | static struct acpi_processor_performance *acpi_perf_data[NR_CPUS]; |
351 | |||
352 | /* | ||
353 | * centrino_cpu_early_init_acpi - Do the preregistering with ACPI P-States | ||
354 | * library | ||
355 | * | ||
356 | * Before doing the actual init, we need to do _PSD related setup whenever | ||
357 | * supported by the BIOS. These are handled by this early_init routine. | ||
358 | */ | ||
359 | static int centrino_cpu_early_init_acpi(void) | ||
360 | { | ||
361 | unsigned int i, j; | ||
362 | struct acpi_processor_performance *data; | ||
363 | |||
364 | for_each_cpu(i) { | ||
365 | data = kzalloc(sizeof(struct acpi_processor_performance), | ||
366 | GFP_KERNEL); | ||
367 | if (!data) { | ||
368 | for_each_cpu(j) { | ||
369 | kfree(acpi_perf_data[j]); | ||
370 | acpi_perf_data[j] = NULL; | ||
371 | } | ||
372 | return (-ENOMEM); | ||
373 | } | ||
374 | acpi_perf_data[i] = data; | ||
375 | } | ||
376 | |||
377 | acpi_processor_preregister_performance(acpi_perf_data); | ||
378 | return 0; | ||
379 | } | ||
355 | 380 | ||
356 | /* | 381 | /* |
357 | * centrino_cpu_init_acpi - register with ACPI P-States library | 382 | * centrino_cpu_init_acpi - register with ACPI P-States library |
@@ -365,46 +390,51 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) | |||
365 | unsigned long cur_freq; | 390 | unsigned long cur_freq; |
366 | int result = 0, i; | 391 | int result = 0, i; |
367 | unsigned int cpu = policy->cpu; | 392 | unsigned int cpu = policy->cpu; |
393 | struct acpi_processor_performance *p; | ||
394 | |||
395 | p = acpi_perf_data[cpu]; | ||
368 | 396 | ||
369 | /* register with ACPI core */ | 397 | /* register with ACPI core */ |
370 | if (acpi_processor_register_performance(&p, cpu)) { | 398 | if (acpi_processor_register_performance(p, cpu)) { |
371 | dprintk("obtaining ACPI data failed\n"); | 399 | dprintk(PFX "obtaining ACPI data failed\n"); |
372 | return -EIO; | 400 | return -EIO; |
373 | } | 401 | } |
402 | policy->cpus = p->shared_cpu_map; | ||
403 | policy->shared_type = p->shared_type; | ||
374 | 404 | ||
375 | /* verify the acpi_data */ | 405 | /* verify the acpi_data */ |
376 | if (p.state_count <= 1) { | 406 | if (p->state_count <= 1) { |
377 | dprintk("No P-States\n"); | 407 | dprintk("No P-States\n"); |
378 | result = -ENODEV; | 408 | result = -ENODEV; |
379 | goto err_unreg; | 409 | goto err_unreg; |
380 | } | 410 | } |
381 | 411 | ||
382 | if ((p.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || | 412 | if ((p->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || |
383 | (p.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { | 413 | (p->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { |
384 | dprintk("Invalid control/status registers (%x - %x)\n", | 414 | dprintk("Invalid control/status registers (%x - %x)\n", |
385 | p.control_register.space_id, p.status_register.space_id); | 415 | p->control_register.space_id, p->status_register.space_id); |
386 | result = -EIO; | 416 | result = -EIO; |
387 | goto err_unreg; | 417 | goto err_unreg; |
388 | } | 418 | } |
389 | 419 | ||
390 | for (i=0; i<p.state_count; i++) { | 420 | for (i=0; i<p->state_count; i++) { |
391 | if (p.states[i].control != p.states[i].status) { | 421 | if (p->states[i].control != p->states[i].status) { |
392 | dprintk("Different control (%llu) and status values (%llu)\n", | 422 | dprintk("Different control (%llu) and status values (%llu)\n", |
393 | p.states[i].control, p.states[i].status); | 423 | p->states[i].control, p->states[i].status); |
394 | result = -EINVAL; | 424 | result = -EINVAL; |
395 | goto err_unreg; | 425 | goto err_unreg; |
396 | } | 426 | } |
397 | 427 | ||
398 | if (!p.states[i].core_frequency) { | 428 | if (!p->states[i].core_frequency) { |
399 | dprintk("Zero core frequency for state %u\n", i); | 429 | dprintk("Zero core frequency for state %u\n", i); |
400 | result = -EINVAL; | 430 | result = -EINVAL; |
401 | goto err_unreg; | 431 | goto err_unreg; |
402 | } | 432 | } |
403 | 433 | ||
404 | if (p.states[i].core_frequency > p.states[0].core_frequency) { | 434 | if (p->states[i].core_frequency > p->states[0].core_frequency) { |
405 | dprintk("P%u has larger frequency (%llu) than P0 (%llu), skipping\n", i, | 435 | dprintk("P%u has larger frequency (%llu) than P0 (%llu), skipping\n", i, |
406 | p.states[i].core_frequency, p.states[0].core_frequency); | 436 | p->states[i].core_frequency, p->states[0].core_frequency); |
407 | p.states[i].core_frequency = 0; | 437 | p->states[i].core_frequency = 0; |
408 | continue; | 438 | continue; |
409 | } | 439 | } |
410 | } | 440 | } |
@@ -416,26 +446,26 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) | |||
416 | } | 446 | } |
417 | 447 | ||
418 | centrino_model[cpu]->model_name=NULL; | 448 | centrino_model[cpu]->model_name=NULL; |
419 | centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000; | 449 | centrino_model[cpu]->max_freq = p->states[0].core_frequency * 1000; |
420 | centrino_model[cpu]->op_points = kmalloc(sizeof(struct cpufreq_frequency_table) * | 450 | centrino_model[cpu]->op_points = kmalloc(sizeof(struct cpufreq_frequency_table) * |
421 | (p.state_count + 1), GFP_KERNEL); | 451 | (p->state_count + 1), GFP_KERNEL); |
422 | if (!centrino_model[cpu]->op_points) { | 452 | if (!centrino_model[cpu]->op_points) { |
423 | result = -ENOMEM; | 453 | result = -ENOMEM; |
424 | goto err_kfree; | 454 | goto err_kfree; |
425 | } | 455 | } |
426 | 456 | ||
427 | for (i=0; i<p.state_count; i++) { | 457 | for (i=0; i<p->state_count; i++) { |
428 | centrino_model[cpu]->op_points[i].index = p.states[i].control; | 458 | centrino_model[cpu]->op_points[i].index = p->states[i].control; |
429 | centrino_model[cpu]->op_points[i].frequency = p.states[i].core_frequency * 1000; | 459 | centrino_model[cpu]->op_points[i].frequency = p->states[i].core_frequency * 1000; |
430 | dprintk("adding state %i with frequency %u and control value %04x\n", | 460 | dprintk("adding state %i with frequency %u and control value %04x\n", |
431 | i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index); | 461 | i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index); |
432 | } | 462 | } |
433 | centrino_model[cpu]->op_points[p.state_count].frequency = CPUFREQ_TABLE_END; | 463 | centrino_model[cpu]->op_points[p->state_count].frequency = CPUFREQ_TABLE_END; |
434 | 464 | ||
435 | cur_freq = get_cur_freq(cpu); | 465 | cur_freq = get_cur_freq(cpu); |
436 | 466 | ||
437 | for (i=0; i<p.state_count; i++) { | 467 | for (i=0; i<p->state_count; i++) { |
438 | if (!p.states[i].core_frequency) { | 468 | if (!p->states[i].core_frequency) { |
439 | dprintk("skipping state %u\n", i); | 469 | dprintk("skipping state %u\n", i); |
440 | centrino_model[cpu]->op_points[i].frequency = CPUFREQ_ENTRY_INVALID; | 470 | centrino_model[cpu]->op_points[i].frequency = CPUFREQ_ENTRY_INVALID; |
441 | continue; | 471 | continue; |
@@ -451,7 +481,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) | |||
451 | } | 481 | } |
452 | 482 | ||
453 | if (cur_freq == centrino_model[cpu]->op_points[i].frequency) | 483 | if (cur_freq == centrino_model[cpu]->op_points[i].frequency) |
454 | p.state = i; | 484 | p->state = i; |
455 | } | 485 | } |
456 | 486 | ||
457 | /* notify BIOS that we exist */ | 487 | /* notify BIOS that we exist */ |
@@ -464,12 +494,13 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) | |||
464 | err_kfree: | 494 | err_kfree: |
465 | kfree(centrino_model[cpu]); | 495 | kfree(centrino_model[cpu]); |
466 | err_unreg: | 496 | err_unreg: |
467 | acpi_processor_unregister_performance(&p, cpu); | 497 | acpi_processor_unregister_performance(p, cpu); |
468 | dprintk("invalid ACPI data\n"); | 498 | dprintk(PFX "invalid ACPI data\n"); |
469 | return (result); | 499 | return (result); |
470 | } | 500 | } |
471 | #else | 501 | #else |
472 | static inline int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { return -ENODEV; } | 502 | static inline int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { return -ENODEV; } |
503 | static inline int centrino_cpu_early_init_acpi(void) { return 0; } | ||
473 | #endif | 504 | #endif |
474 | 505 | ||
475 | static int centrino_cpu_init(struct cpufreq_policy *policy) | 506 | static int centrino_cpu_init(struct cpufreq_policy *policy) |
@@ -555,10 +586,15 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy) | |||
555 | 586 | ||
556 | #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI | 587 | #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI |
557 | if (!centrino_model[cpu]->model_name) { | 588 | if (!centrino_model[cpu]->model_name) { |
558 | dprintk("unregistering and freeing ACPI data\n"); | 589 | static struct acpi_processor_performance *p; |
559 | acpi_processor_unregister_performance(&p, cpu); | 590 | |
560 | kfree(centrino_model[cpu]->op_points); | 591 | if (acpi_perf_data[cpu]) { |
561 | kfree(centrino_model[cpu]); | 592 | p = acpi_perf_data[cpu]; |
593 | dprintk("unregistering and freeing ACPI data\n"); | ||
594 | acpi_processor_unregister_performance(p, cpu); | ||
595 | kfree(centrino_model[cpu]->op_points); | ||
596 | kfree(centrino_model[cpu]); | ||
597 | } | ||
562 | } | 598 | } |
563 | #endif | 599 | #endif |
564 | 600 | ||
@@ -592,63 +628,128 @@ static int centrino_target (struct cpufreq_policy *policy, | |||
592 | unsigned int relation) | 628 | unsigned int relation) |
593 | { | 629 | { |
594 | unsigned int newstate = 0; | 630 | unsigned int newstate = 0; |
595 | unsigned int msr, oldmsr, h, cpu = policy->cpu; | 631 | unsigned int msr, oldmsr = 0, h = 0, cpu = policy->cpu; |
596 | struct cpufreq_freqs freqs; | 632 | struct cpufreq_freqs freqs; |
633 | cpumask_t online_policy_cpus; | ||
597 | cpumask_t saved_mask; | 634 | cpumask_t saved_mask; |
598 | int retval; | 635 | cpumask_t set_mask; |
636 | cpumask_t covered_cpus; | ||
637 | int retval = 0; | ||
638 | unsigned int j, k, first_cpu, tmp; | ||
599 | 639 | ||
600 | if (centrino_model[cpu] == NULL) | 640 | if (unlikely(centrino_model[cpu] == NULL)) |
601 | return -ENODEV; | 641 | return -ENODEV; |
602 | 642 | ||
603 | /* | 643 | if (unlikely(cpufreq_frequency_table_target(policy, |
604 | * Support for SMP systems. | 644 | centrino_model[cpu]->op_points, |
605 | * Make sure we are running on the CPU that wants to change frequency | 645 | target_freq, |
606 | */ | 646 | relation, |
607 | saved_mask = current->cpus_allowed; | 647 | &newstate))) { |
608 | set_cpus_allowed(current, policy->cpus); | 648 | return -EINVAL; |
609 | if (!cpu_isset(smp_processor_id(), policy->cpus)) { | ||
610 | dprintk("couldn't limit to CPUs in this domain\n"); | ||
611 | return(-EAGAIN); | ||
612 | } | 649 | } |
613 | 650 | ||
614 | if (cpufreq_frequency_table_target(policy, centrino_model[cpu]->op_points, target_freq, | 651 | #ifdef CONFIG_HOTPLUG_CPU |
615 | relation, &newstate)) { | 652 | /* cpufreq holds the hotplug lock, so we are safe from here on */ |
616 | retval = -EINVAL; | 653 | cpus_and(online_policy_cpus, cpu_online_map, policy->cpus); |
617 | goto migrate_end; | 654 | #else |
618 | } | 655 | online_policy_cpus = policy->cpus; |
656 | #endif | ||
619 | 657 | ||
620 | msr = centrino_model[cpu]->op_points[newstate].index; | 658 | saved_mask = current->cpus_allowed; |
621 | rdmsr(MSR_IA32_PERF_CTL, oldmsr, h); | 659 | first_cpu = 1; |
660 | cpus_clear(covered_cpus); | ||
661 | for_each_cpu_mask(j, online_policy_cpus) { | ||
662 | /* | ||
663 | * Support for SMP systems. | ||
664 | * Make sure we are running on CPU that wants to change freq | ||
665 | */ | ||
666 | cpus_clear(set_mask); | ||
667 | if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) | ||
668 | cpus_or(set_mask, set_mask, online_policy_cpus); | ||
669 | else | ||
670 | cpu_set(j, set_mask); | ||
671 | |||
672 | set_cpus_allowed(current, set_mask); | ||
673 | if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) { | ||
674 | dprintk("couldn't limit to CPUs in this domain\n"); | ||
675 | retval = -EAGAIN; | ||
676 | if (first_cpu) { | ||
677 | /* We haven't started the transition yet. */ | ||
678 | goto migrate_end; | ||
679 | } | ||
680 | break; | ||
681 | } | ||
622 | 682 | ||
623 | if (msr == (oldmsr & 0xffff)) { | 683 | msr = centrino_model[cpu]->op_points[newstate].index; |
624 | retval = 0; | 684 | |
625 | dprintk("no change needed - msr was and needs to be %x\n", oldmsr); | 685 | if (first_cpu) { |
626 | goto migrate_end; | 686 | rdmsr(MSR_IA32_PERF_CTL, oldmsr, h); |
627 | } | 687 | if (msr == (oldmsr & 0xffff)) { |
688 | dprintk("no change needed - msr was and needs " | ||
689 | "to be %x\n", oldmsr); | ||
690 | retval = 0; | ||
691 | goto migrate_end; | ||
692 | } | ||
693 | |||
694 | freqs.old = extract_clock(oldmsr, cpu, 0); | ||
695 | freqs.new = extract_clock(msr, cpu, 0); | ||
696 | |||
697 | dprintk("target=%dkHz old=%d new=%d msr=%04x\n", | ||
698 | target_freq, freqs.old, freqs.new, msr); | ||
699 | |||
700 | for_each_cpu_mask(k, online_policy_cpus) { | ||
701 | freqs.cpu = k; | ||
702 | cpufreq_notify_transition(&freqs, | ||
703 | CPUFREQ_PRECHANGE); | ||
704 | } | ||
705 | |||
706 | first_cpu = 0; | ||
707 | /* all but 16 LSB are reserved, treat them with care */ | ||
708 | oldmsr &= ~0xffff; | ||
709 | msr &= 0xffff; | ||
710 | oldmsr |= msr; | ||
711 | } | ||
628 | 712 | ||
629 | freqs.cpu = cpu; | 713 | wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); |
630 | freqs.old = extract_clock(oldmsr, cpu, 0); | 714 | if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) |
631 | freqs.new = extract_clock(msr, cpu, 0); | 715 | break; |
632 | 716 | ||
633 | dprintk("target=%dkHz old=%d new=%d msr=%04x\n", | 717 | cpu_set(j, covered_cpus); |
634 | target_freq, freqs.old, freqs.new, msr); | 718 | } |
635 | 719 | ||
636 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 720 | for_each_cpu_mask(k, online_policy_cpus) { |
721 | freqs.cpu = k; | ||
722 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
723 | } | ||
637 | 724 | ||
638 | /* all but 16 LSB are "reserved", so treat them with | 725 | if (unlikely(retval)) { |
639 | care */ | 726 | /* |
640 | oldmsr &= ~0xffff; | 727 | * We have failed halfway through the frequency change. |
641 | msr &= 0xffff; | 728 | * We have sent callbacks to policy->cpus and |
642 | oldmsr |= msr; | 729 | * MSRs have already been written on coverd_cpus. |
730 | * Best effort undo.. | ||
731 | */ | ||
643 | 732 | ||
644 | wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); | 733 | if (!cpus_empty(covered_cpus)) { |
734 | for_each_cpu_mask(j, covered_cpus) { | ||
735 | set_cpus_allowed(current, cpumask_of_cpu(j)); | ||
736 | wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); | ||
737 | } | ||
738 | } | ||
645 | 739 | ||
646 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 740 | tmp = freqs.new; |
741 | freqs.new = freqs.old; | ||
742 | freqs.old = tmp; | ||
743 | for_each_cpu_mask(j, online_policy_cpus) { | ||
744 | freqs.cpu = j; | ||
745 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
746 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
747 | } | ||
748 | } | ||
647 | 749 | ||
648 | retval = 0; | ||
649 | migrate_end: | 750 | migrate_end: |
650 | set_cpus_allowed(current, saved_mask); | 751 | set_cpus_allowed(current, saved_mask); |
651 | return (retval); | 752 | return 0; |
652 | } | 753 | } |
653 | 754 | ||
654 | static struct freq_attr* centrino_attr[] = { | 755 | static struct freq_attr* centrino_attr[] = { |
@@ -690,12 +791,25 @@ static int __init centrino_init(void) | |||
690 | if (!cpu_has(cpu, X86_FEATURE_EST)) | 791 | if (!cpu_has(cpu, X86_FEATURE_EST)) |
691 | return -ENODEV; | 792 | return -ENODEV; |
692 | 793 | ||
794 | centrino_cpu_early_init_acpi(); | ||
795 | |||
693 | return cpufreq_register_driver(¢rino_driver); | 796 | return cpufreq_register_driver(¢rino_driver); |
694 | } | 797 | } |
695 | 798 | ||
696 | static void __exit centrino_exit(void) | 799 | static void __exit centrino_exit(void) |
697 | { | 800 | { |
801 | #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI | ||
802 | unsigned int j; | ||
803 | #endif | ||
804 | |||
698 | cpufreq_unregister_driver(¢rino_driver); | 805 | cpufreq_unregister_driver(¢rino_driver); |
806 | |||
807 | #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI | ||
808 | for_each_cpu(j) { | ||
809 | kfree(acpi_perf_data[j]); | ||
810 | acpi_perf_data[j] = NULL; | ||
811 | } | ||
812 | #endif | ||
699 | } | 813 | } |
700 | 814 | ||
701 | MODULE_AUTHOR ("Jeremy Fitzhardinge <jeremy@goop.org>"); | 815 | MODULE_AUTHOR ("Jeremy Fitzhardinge <jeremy@goop.org>"); |
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c index 00f2e058797c..fc32c8028e24 100644 --- a/arch/i386/kernel/cpu/cyrix.c +++ b/arch/i386/kernel/cpu/cyrix.c | |||
@@ -184,7 +184,7 @@ static void __init geode_configure(void) | |||
184 | 184 | ||
185 | 185 | ||
186 | #ifdef CONFIG_PCI | 186 | #ifdef CONFIG_PCI |
187 | static struct pci_device_id cyrix_55x0[] = { | 187 | static struct pci_device_id __initdata cyrix_55x0[] = { |
188 | { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) }, | 188 | { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) }, |
189 | { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) }, | 189 | { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) }, |
190 | { }, | 190 | { }, |
@@ -272,14 +272,15 @@ static void __init init_cyrix(struct cpuinfo_x86 *c) | |||
272 | 272 | ||
273 | printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bugs.\n"); | 273 | printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bugs.\n"); |
274 | isa_dma_bridge_buggy = 2; | 274 | isa_dma_bridge_buggy = 2; |
275 | #endif | 275 | |
276 | c->x86_cache_size=16; /* Yep 16K integrated cache thats it */ | 276 | |
277 | |||
278 | /* | 277 | /* |
279 | * The 5510/5520 companion chips have a funky PIT. | 278 | * The 5510/5520 companion chips have a funky PIT. |
280 | */ | 279 | */ |
281 | if (pci_dev_present(cyrix_55x0)) | 280 | if (pci_dev_present(cyrix_55x0)) |
282 | pit_latch_buggy = 1; | 281 | pit_latch_buggy = 1; |
282 | #endif | ||
283 | c->x86_cache_size=16; /* Yep 16K integrated cache thats it */ | ||
283 | 284 | ||
284 | /* GXm supports extended cpuid levels 'ala' AMD */ | 285 | /* GXm supports extended cpuid levels 'ala' AMD */ |
285 | if (c->cpuid_level == 2) { | 286 | if (c->cpuid_level == 2) { |
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index f94cdb7aca50..a19fcb262dbb 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c | |||
@@ -52,7 +52,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
52 | 52 | ||
53 | /* VIA/Cyrix/Centaur-defined */ | 53 | /* VIA/Cyrix/Centaur-defined */ |
54 | NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en", | 54 | NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en", |
55 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 55 | "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL, |
56 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 56 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
57 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 57 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
58 | 58 | ||
diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c index d75524758daf..c4351972d9af 100644 --- a/arch/i386/kernel/i387.c +++ b/arch/i386/kernel/i387.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #define HAVE_HWFP 1 | 25 | #define HAVE_HWFP 1 |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | static unsigned long mxcsr_feature_mask = 0xffffffff; | 28 | static unsigned long mxcsr_feature_mask __read_mostly = 0xffffffff; |
29 | 29 | ||
30 | void mxcsr_feature_mask_init(void) | 30 | void mxcsr_feature_mask_init(void) |
31 | { | 31 | { |
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index 323ef8ab3244..b7636b96e104 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c | |||
@@ -271,8 +271,8 @@ static int i8259A_shutdown(struct sys_device *dev) | |||
271 | * the kernel initialization code can get it | 271 | * the kernel initialization code can get it |
272 | * out of. | 272 | * out of. |
273 | */ | 273 | */ |
274 | outb(0xff, 0x21); /* mask all of 8259A-1 */ | 274 | outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ |
275 | outb(0xff, 0xA1); /* mask all of 8259A-1 */ | 275 | outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ |
276 | return 0; | 276 | return 0; |
277 | } | 277 | } |
278 | 278 | ||
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index d70f2ade5cde..a62df3e764c5 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -267,7 +267,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
267 | # include <linux/slab.h> /* kmalloc() */ | 267 | # include <linux/slab.h> /* kmalloc() */ |
268 | # include <linux/timer.h> /* time_after() */ | 268 | # include <linux/timer.h> /* time_after() */ |
269 | 269 | ||
270 | # ifdef CONFIG_BALANCED_IRQ_DEBUG | 270 | #ifdef CONFIG_BALANCED_IRQ_DEBUG |
271 | # define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0) | 271 | # define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0) |
272 | # define Dprintk(x...) do { TDprintk(x); } while (0) | 272 | # define Dprintk(x...) do { TDprintk(x); } while (0) |
273 | # else | 273 | # else |
@@ -275,10 +275,15 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
275 | # define Dprintk(x...) | 275 | # define Dprintk(x...) |
276 | # endif | 276 | # endif |
277 | 277 | ||
278 | |||
279 | #define IRQBALANCE_CHECK_ARCH -999 | 278 | #define IRQBALANCE_CHECK_ARCH -999 |
280 | static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; | 279 | #define MAX_BALANCED_IRQ_INTERVAL (5*HZ) |
281 | static int physical_balance = 0; | 280 | #define MIN_BALANCED_IRQ_INTERVAL (HZ/2) |
281 | #define BALANCED_IRQ_MORE_DELTA (HZ/10) | ||
282 | #define BALANCED_IRQ_LESS_DELTA (HZ) | ||
283 | |||
284 | static int irqbalance_disabled __read_mostly = IRQBALANCE_CHECK_ARCH; | ||
285 | static int physical_balance __read_mostly; | ||
286 | static long balanced_irq_interval __read_mostly = MAX_BALANCED_IRQ_INTERVAL; | ||
282 | 287 | ||
283 | static struct irq_cpu_info { | 288 | static struct irq_cpu_info { |
284 | unsigned long * last_irq; | 289 | unsigned long * last_irq; |
@@ -297,12 +302,14 @@ static struct irq_cpu_info { | |||
297 | 302 | ||
298 | #define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i])) | 303 | #define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i])) |
299 | 304 | ||
300 | #define MAX_BALANCED_IRQ_INTERVAL (5*HZ) | 305 | static cpumask_t balance_irq_affinity[NR_IRQS] = { |
301 | #define MIN_BALANCED_IRQ_INTERVAL (HZ/2) | 306 | [0 ... NR_IRQS-1] = CPU_MASK_ALL |
302 | #define BALANCED_IRQ_MORE_DELTA (HZ/10) | 307 | }; |
303 | #define BALANCED_IRQ_LESS_DELTA (HZ) | ||
304 | 308 | ||
305 | static long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL; | 309 | void set_balance_irq_affinity(unsigned int irq, cpumask_t mask) |
310 | { | ||
311 | balance_irq_affinity[irq] = mask; | ||
312 | } | ||
306 | 313 | ||
307 | static unsigned long move(int curr_cpu, cpumask_t allowed_mask, | 314 | static unsigned long move(int curr_cpu, cpumask_t allowed_mask, |
308 | unsigned long now, int direction) | 315 | unsigned long now, int direction) |
@@ -340,7 +347,7 @@ static inline void balance_irq(int cpu, int irq) | |||
340 | if (irqbalance_disabled) | 347 | if (irqbalance_disabled) |
341 | return; | 348 | return; |
342 | 349 | ||
343 | cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]); | 350 | cpus_and(allowed_mask, cpu_online_map, balance_irq_affinity[irq]); |
344 | new_cpu = move(cpu, allowed_mask, now, 1); | 351 | new_cpu = move(cpu, allowed_mask, now, 1); |
345 | if (cpu != new_cpu) { | 352 | if (cpu != new_cpu) { |
346 | set_pending_irq(irq, cpumask_of_cpu(new_cpu)); | 353 | set_pending_irq(irq, cpumask_of_cpu(new_cpu)); |
@@ -529,7 +536,9 @@ tryanotherirq: | |||
529 | } | 536 | } |
530 | } | 537 | } |
531 | 538 | ||
532 | cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]); | 539 | cpus_and(allowed_mask, |
540 | cpu_online_map, | ||
541 | balance_irq_affinity[selected_irq]); | ||
533 | target_cpu_mask = cpumask_of_cpu(min_loaded); | 542 | target_cpu_mask = cpumask_of_cpu(min_loaded); |
534 | cpus_and(tmp, target_cpu_mask, allowed_mask); | 543 | cpus_and(tmp, target_cpu_mask, allowed_mask); |
535 | 544 | ||
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index f3a9c78c4a24..248e922ee13a 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c | |||
@@ -42,8 +42,8 @@ union irq_ctx { | |||
42 | u32 stack[THREAD_SIZE/sizeof(u32)]; | 42 | u32 stack[THREAD_SIZE/sizeof(u32)]; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | static union irq_ctx *hardirq_ctx[NR_CPUS]; | 45 | static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly; |
46 | static union irq_ctx *softirq_ctx[NR_CPUS]; | 46 | static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | /* | 49 | /* |
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 38806f427849..395a9a6dff88 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c | |||
@@ -607,7 +607,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
607 | struct die_args *args = (struct die_args *)data; | 607 | struct die_args *args = (struct die_args *)data; |
608 | int ret = NOTIFY_DONE; | 608 | int ret = NOTIFY_DONE; |
609 | 609 | ||
610 | if (args->regs && user_mode(args->regs)) | 610 | if (args->regs && user_mode_vm(args->regs)) |
611 | return ret; | 611 | return ret; |
612 | 612 | ||
613 | switch (val) { | 613 | switch (val) { |
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index e7c138f66c5a..0a865889b2a9 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c | |||
@@ -91,7 +91,10 @@ MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver"); | |||
91 | MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>"); | 91 | MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>"); |
92 | MODULE_LICENSE("GPL"); | 92 | MODULE_LICENSE("GPL"); |
93 | 93 | ||
94 | #define MICROCODE_VERSION "1.14" | 94 | static int verbose; |
95 | module_param(verbose, int, 0644); | ||
96 | |||
97 | #define MICROCODE_VERSION "1.14a" | ||
95 | 98 | ||
96 | #define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ | 99 | #define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ |
97 | #define MC_HEADER_SIZE (sizeof (microcode_header_t)) /* 48 bytes */ | 100 | #define MC_HEADER_SIZE (sizeof (microcode_header_t)) /* 48 bytes */ |
@@ -122,14 +125,15 @@ static unsigned int user_buffer_size; /* it's size */ | |||
122 | 125 | ||
123 | typedef enum mc_error_code { | 126 | typedef enum mc_error_code { |
124 | MC_SUCCESS = 0, | 127 | MC_SUCCESS = 0, |
125 | MC_NOTFOUND = 1, | 128 | MC_IGNORED = 1, |
126 | MC_MARKED = 2, | 129 | MC_NOTFOUND = 2, |
127 | MC_ALLOCATED = 3, | 130 | MC_MARKED = 3, |
131 | MC_ALLOCATED = 4, | ||
128 | } mc_error_code_t; | 132 | } mc_error_code_t; |
129 | 133 | ||
130 | static struct ucode_cpu_info { | 134 | static struct ucode_cpu_info { |
131 | unsigned int sig; | 135 | unsigned int sig; |
132 | unsigned int pf; | 136 | unsigned int pf, orig_pf; |
133 | unsigned int rev; | 137 | unsigned int rev; |
134 | unsigned int cksum; | 138 | unsigned int cksum; |
135 | mc_error_code_t err; | 139 | mc_error_code_t err; |
@@ -164,6 +168,7 @@ static void collect_cpu_info (void *unused) | |||
164 | rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); | 168 | rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); |
165 | uci->pf = 1 << ((val[1] >> 18) & 7); | 169 | uci->pf = 1 << ((val[1] >> 18) & 7); |
166 | } | 170 | } |
171 | uci->orig_pf = uci->pf; | ||
167 | } | 172 | } |
168 | 173 | ||
169 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); | 174 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); |
@@ -197,21 +202,34 @@ static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_he | |||
197 | pr_debug(" Checksum 0x%x\n", cksum); | 202 | pr_debug(" Checksum 0x%x\n", cksum); |
198 | 203 | ||
199 | if (mc_header->rev < uci->rev) { | 204 | if (mc_header->rev < uci->rev) { |
200 | printk(KERN_ERR "microcode: CPU%d not 'upgrading' to earlier revision" | 205 | if (uci->err == MC_NOTFOUND) { |
201 | " 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); | 206 | uci->err = MC_IGNORED; |
202 | goto out; | 207 | uci->cksum = mc_header->rev; |
208 | } else if (uci->err == MC_IGNORED && uci->cksum < mc_header->rev) | ||
209 | uci->cksum = mc_header->rev; | ||
203 | } else if (mc_header->rev == uci->rev) { | 210 | } else if (mc_header->rev == uci->rev) { |
204 | /* notify the caller of success on this cpu */ | 211 | if (uci->err < MC_MARKED) { |
205 | uci->err = MC_SUCCESS; | 212 | /* notify the caller of success on this cpu */ |
206 | goto out; | 213 | uci->err = MC_SUCCESS; |
214 | } | ||
215 | } else if (uci->err != MC_ALLOCATED || mc_header->rev > uci->mc->hdr.rev) { | ||
216 | pr_debug("microcode: CPU%d found a matching microcode update with " | ||
217 | " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); | ||
218 | uci->cksum = cksum; | ||
219 | uci->pf = pf; /* keep the original mc pf for cksum calculation */ | ||
220 | uci->err = MC_MARKED; /* found the match */ | ||
221 | for_each_online_cpu(cpu_num) { | ||
222 | if (ucode_cpu_info + cpu_num != uci | ||
223 | && ucode_cpu_info[cpu_num].mc == uci->mc) { | ||
224 | uci->mc = NULL; | ||
225 | break; | ||
226 | } | ||
227 | } | ||
228 | if (uci->mc != NULL) { | ||
229 | vfree(uci->mc); | ||
230 | uci->mc = NULL; | ||
231 | } | ||
207 | } | 232 | } |
208 | |||
209 | pr_debug("microcode: CPU%d found a matching microcode update with " | ||
210 | " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); | ||
211 | uci->cksum = cksum; | ||
212 | uci->pf = pf; /* keep the original mc pf for cksum calculation */ | ||
213 | uci->err = MC_MARKED; /* found the match */ | ||
214 | out: | ||
215 | return; | 233 | return; |
216 | } | 234 | } |
217 | 235 | ||
@@ -253,10 +271,8 @@ static int find_matching_ucodes (void) | |||
253 | 271 | ||
254 | for_each_online_cpu(cpu_num) { | 272 | for_each_online_cpu(cpu_num) { |
255 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; | 273 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; |
256 | if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/ | ||
257 | continue; | ||
258 | 274 | ||
259 | if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->pf)) | 275 | if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->orig_pf)) |
260 | mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum); | 276 | mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum); |
261 | } | 277 | } |
262 | 278 | ||
@@ -295,9 +311,8 @@ static int find_matching_ucodes (void) | |||
295 | } | 311 | } |
296 | for_each_online_cpu(cpu_num) { | 312 | for_each_online_cpu(cpu_num) { |
297 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; | 313 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; |
298 | if (uci->err != MC_NOTFOUND) /* already found a match or not an online cpu*/ | 314 | |
299 | continue; | 315 | if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->orig_pf)) { |
300 | if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->pf)) { | ||
301 | mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum); | 316 | mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum); |
302 | } | 317 | } |
303 | } | 318 | } |
@@ -368,6 +383,13 @@ static void do_update_one (void * unused) | |||
368 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; | 383 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; |
369 | 384 | ||
370 | if (uci->mc == NULL) { | 385 | if (uci->mc == NULL) { |
386 | if (verbose) { | ||
387 | if (uci->err == MC_SUCCESS) | ||
388 | printk(KERN_INFO "microcode: CPU%d already at revision 0x%x\n", | ||
389 | cpu_num, uci->rev); | ||
390 | else | ||
391 | printk(KERN_INFO "microcode: No new microcode data for CPU%d\n", cpu_num); | ||
392 | } | ||
371 | return; | 393 | return; |
372 | } | 394 | } |
373 | 395 | ||
@@ -426,6 +448,9 @@ out_free: | |||
426 | ucode_cpu_info[j].mc = NULL; | 448 | ucode_cpu_info[j].mc = NULL; |
427 | } | 449 | } |
428 | } | 450 | } |
451 | if (ucode_cpu_info[i].err == MC_IGNORED && verbose) | ||
452 | printk(KERN_WARNING "microcode: CPU%d not 'upgrading' to earlier revision" | ||
453 | " 0x%x (current=0x%x)\n", i, ucode_cpu_info[i].cksum, ucode_cpu_info[i].rev); | ||
429 | } | 454 | } |
430 | out: | 455 | out: |
431 | return error; | 456 | return error; |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index dd6b0e3386ce..e6023970aa40 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/crash_dump.h> | 48 | #include <linux/crash_dump.h> |
49 | #include <linux/dmi.h> | 49 | #include <linux/dmi.h> |
50 | #include <linux/pfn.h> | 50 | #include <linux/pfn.h> |
51 | #include <linux/suspend.h> | ||
51 | 52 | ||
52 | #include <video/edid.h> | 53 | #include <video/edid.h> |
53 | 54 | ||
@@ -1434,6 +1435,111 @@ static void set_mca_bus(int x) | |||
1434 | static void set_mca_bus(int x) { } | 1435 | static void set_mca_bus(int x) { } |
1435 | #endif | 1436 | #endif |
1436 | 1437 | ||
1438 | #ifdef CONFIG_SOFTWARE_SUSPEND | ||
1439 | static void __init mark_nosave_page_range(unsigned long start, unsigned long end) | ||
1440 | { | ||
1441 | struct page *page; | ||
1442 | while (start <= end) { | ||
1443 | page = pfn_to_page(start); | ||
1444 | SetPageNosave(page); | ||
1445 | start++; | ||
1446 | } | ||
1447 | } | ||
1448 | |||
1449 | static void __init e820_nosave_reserved_pages(void) | ||
1450 | { | ||
1451 | int i; | ||
1452 | unsigned long r_start = 0, r_end = 0; | ||
1453 | |||
1454 | /* Assume e820 map is sorted */ | ||
1455 | for (i = 0; i < e820.nr_map; i++) { | ||
1456 | struct e820entry *ei = &e820.map[i]; | ||
1457 | unsigned long start, end; | ||
1458 | |||
1459 | start = PFN_DOWN(ei->addr); | ||
1460 | end = PFN_UP(ei->addr + ei->size); | ||
1461 | if (start >= end) | ||
1462 | continue; | ||
1463 | if (ei->type == E820_RESERVED) | ||
1464 | continue; | ||
1465 | r_end = start; | ||
1466 | /* | ||
1467 | * Highmem 'Reserved' pages are marked as reserved, swsusp | ||
1468 | * will not save/restore them, so we ignore these pages here. | ||
1469 | */ | ||
1470 | if (r_end > max_low_pfn) | ||
1471 | r_end = max_low_pfn; | ||
1472 | if (r_end > r_start) | ||
1473 | mark_nosave_page_range(r_start, r_end-1); | ||
1474 | if (r_end >= max_low_pfn) | ||
1475 | break; | ||
1476 | r_start = end; | ||
1477 | } | ||
1478 | } | ||
1479 | |||
1480 | static void __init e820_save_acpi_pages(void) | ||
1481 | { | ||
1482 | int i; | ||
1483 | |||
1484 | /* Assume e820 map is sorted */ | ||
1485 | for (i = 0; i < e820.nr_map; i++) { | ||
1486 | struct e820entry *ei = &e820.map[i]; | ||
1487 | unsigned long start, end; | ||
1488 | |||
1489 | start = ei->addr; | ||
1490 | end = ei->addr + ei->size; | ||
1491 | if (start >= end) | ||
1492 | continue; | ||
1493 | if (ei->type != E820_ACPI && ei->type != E820_NVS) | ||
1494 | continue; | ||
1495 | /* | ||
1496 | * If the region is below max_low_pfn, it will be | ||
1497 | * saved/restored by swsusp follow 'RAM' type. | ||
1498 | */ | ||
1499 | if (start < (max_low_pfn << PAGE_SHIFT)) | ||
1500 | start = max_low_pfn << PAGE_SHIFT; | ||
1501 | /* | ||
1502 | * Highmem pages (ACPI NVS/Data) are reserved, but swsusp | ||
1503 | * highmem save/restore will not save/restore them. We marked | ||
1504 | * them as arch saveable pages here | ||
1505 | */ | ||
1506 | if (end > start) | ||
1507 | swsusp_add_arch_pages(start, end); | ||
1508 | } | ||
1509 | } | ||
1510 | |||
1511 | extern char __start_rodata, __end_rodata; | ||
1512 | /* | ||
1513 | * BIOS reserved region/hole - no save/restore | ||
1514 | * ACPI NVS - save/restore | ||
1515 | * ACPI Data - this is a little tricky, the mem could be used by OS after OS | ||
1516 | * reads tables from the region, but anyway save/restore the memory hasn't any | ||
1517 | * side effect and Linux runtime module load/unload might use it. | ||
1518 | * kernel rodata - no save/restore (kernel rodata isn't changed) | ||
1519 | */ | ||
1520 | static int __init mark_nosave_pages(void) | ||
1521 | { | ||
1522 | unsigned long pfn_start, pfn_end; | ||
1523 | |||
1524 | /* FIXME: provide a version for efi BIOS */ | ||
1525 | if (efi_enabled) | ||
1526 | return 0; | ||
1527 | /* BIOS reserved regions & holes */ | ||
1528 | e820_nosave_reserved_pages(); | ||
1529 | |||
1530 | /* kernel rodata */ | ||
1531 | pfn_start = PFN_UP(virt_to_phys(&__start_rodata)); | ||
1532 | pfn_end = PFN_DOWN(virt_to_phys(&__end_rodata)); | ||
1533 | mark_nosave_page_range(pfn_start, pfn_end-1); | ||
1534 | |||
1535 | /* record ACPI Data/NVS as saveable */ | ||
1536 | e820_save_acpi_pages(); | ||
1537 | |||
1538 | return 0; | ||
1539 | } | ||
1540 | core_initcall(mark_nosave_pages); | ||
1541 | #endif | ||
1542 | |||
1437 | /* | 1543 | /* |
1438 | * Determine if we were loaded by an EFI loader. If so, then we have also been | 1544 | * Determine if we were loaded by an EFI loader. If so, then we have also been |
1439 | * passed the efi memmap, systab, etc., so we should use these data structures | 1545 | * passed the efi memmap, systab, etc., so we should use these data structures |
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c index 52b3ed5d2cb5..989c85255dbe 100644 --- a/arch/i386/kernel/srat.c +++ b/arch/i386/kernel/srat.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #define NODE_ARRAY_OFFSET(x) ((x) % 8) /* 8 bits/char */ | 39 | #define NODE_ARRAY_OFFSET(x) ((x) % 8) /* 8 bits/char */ |
40 | #define BMAP_SET(bmap, bit) ((bmap)[NODE_ARRAY_INDEX(bit)] |= 1 << NODE_ARRAY_OFFSET(bit)) | 40 | #define BMAP_SET(bmap, bit) ((bmap)[NODE_ARRAY_INDEX(bit)] |= 1 << NODE_ARRAY_OFFSET(bit)) |
41 | #define BMAP_TEST(bmap, bit) ((bmap)[NODE_ARRAY_INDEX(bit)] & (1 << NODE_ARRAY_OFFSET(bit))) | 41 | #define BMAP_TEST(bmap, bit) ((bmap)[NODE_ARRAY_INDEX(bit)] & (1 << NODE_ARRAY_OFFSET(bit))) |
42 | #define MAX_PXM_DOMAINS 256 /* 1 byte and no promises about values */ | ||
43 | /* bitmap length; _PXM is at most 255 */ | 42 | /* bitmap length; _PXM is at most 255 */ |
44 | #define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8) | 43 | #define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8) |
45 | static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */ | 44 | static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */ |
@@ -213,19 +212,11 @@ static __init void node_read_chunk(int nid, struct node_memory_chunk_s *memory_c | |||
213 | node_end_pfn[nid] = memory_chunk->end_pfn; | 212 | node_end_pfn[nid] = memory_chunk->end_pfn; |
214 | } | 213 | } |
215 | 214 | ||
216 | static u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */ | ||
217 | |||
218 | int pxm_to_node(int pxm) | ||
219 | { | ||
220 | return pxm_to_nid_map[pxm]; | ||
221 | } | ||
222 | |||
223 | /* Parse the ACPI Static Resource Affinity Table */ | 215 | /* Parse the ACPI Static Resource Affinity Table */ |
224 | static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) | 216 | static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) |
225 | { | 217 | { |
226 | u8 *start, *end, *p; | 218 | u8 *start, *end, *p; |
227 | int i, j, nid; | 219 | int i, j, nid; |
228 | u8 nid_to_pxm_map[MAX_NUMNODES];/* logical node ID to _PXM map */ | ||
229 | 220 | ||
230 | start = (u8 *)(&(sratp->reserved) + 1); /* skip header */ | 221 | start = (u8 *)(&(sratp->reserved) + 1); /* skip header */ |
231 | p = start; | 222 | p = start; |
@@ -235,10 +226,6 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) | |||
235 | memset(node_memory_chunk, 0, sizeof(node_memory_chunk)); | 226 | memset(node_memory_chunk, 0, sizeof(node_memory_chunk)); |
236 | memset(zholes_size, 0, sizeof(zholes_size)); | 227 | memset(zholes_size, 0, sizeof(zholes_size)); |
237 | 228 | ||
238 | /* -1 in these maps means not available */ | ||
239 | memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map)); | ||
240 | memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map)); | ||
241 | |||
242 | num_memory_chunks = 0; | 229 | num_memory_chunks = 0; |
243 | while (p < end) { | 230 | while (p < end) { |
244 | switch (*p) { | 231 | switch (*p) { |
@@ -278,9 +265,7 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) | |||
278 | nodes_clear(node_online_map); | 265 | nodes_clear(node_online_map); |
279 | for (i = 0; i < MAX_PXM_DOMAINS; i++) { | 266 | for (i = 0; i < MAX_PXM_DOMAINS; i++) { |
280 | if (BMAP_TEST(pxm_bitmap, i)) { | 267 | if (BMAP_TEST(pxm_bitmap, i)) { |
281 | nid = num_online_nodes(); | 268 | int nid = acpi_map_pxm_to_node(i); |
282 | pxm_to_nid_map[i] = nid; | ||
283 | nid_to_pxm_map[nid] = i; | ||
284 | node_set_online(nid); | 269 | node_set_online(nid); |
285 | } | 270 | } |
286 | } | 271 | } |
@@ -288,7 +273,7 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) | |||
288 | 273 | ||
289 | /* set cnode id in memory chunk structure */ | 274 | /* set cnode id in memory chunk structure */ |
290 | for (i = 0; i < num_memory_chunks; i++) | 275 | for (i = 0; i < num_memory_chunks; i++) |
291 | node_memory_chunk[i].nid = pxm_to_nid_map[node_memory_chunk[i].pxm]; | 276 | node_memory_chunk[i].nid = pxm_to_node(node_memory_chunk[i].pxm); |
292 | 277 | ||
293 | printk("pxm bitmap: "); | 278 | printk("pxm bitmap: "); |
294 | for (i = 0; i < sizeof(pxm_bitmap); i++) { | 279 | for (i = 0; i < sizeof(pxm_bitmap); i++) { |
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index af56987f69b0..dd63d4775398 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S | |||
@@ -316,3 +316,4 @@ ENTRY(sys_call_table) | |||
316 | .long sys_sync_file_range | 316 | .long sys_sync_file_range |
317 | .long sys_tee /* 315 */ | 317 | .long sys_tee /* 315 */ |
318 | .long sys_vmsplice | 318 | .long sys_vmsplice |
319 | .long sys_move_pages | ||
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 0e498369f35e..dcc14477af1f 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -149,6 +149,12 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, | |||
149 | while (valid_stack_ptr(tinfo, (void *)ebp)) { | 149 | while (valid_stack_ptr(tinfo, (void *)ebp)) { |
150 | addr = *(unsigned long *)(ebp + 4); | 150 | addr = *(unsigned long *)(ebp + 4); |
151 | printed = print_addr_and_symbol(addr, log_lvl, printed); | 151 | printed = print_addr_and_symbol(addr, log_lvl, printed); |
152 | /* | ||
153 | * break out of recursive entries (such as | ||
154 | * end_of_stack_stop_unwind_function): | ||
155 | */ | ||
156 | if (ebp == *(unsigned long *)ebp) | ||
157 | break; | ||
152 | ebp = *(unsigned long *)ebp; | 158 | ebp = *(unsigned long *)ebp; |
153 | } | 159 | } |
154 | #else | 160 | #else |
@@ -268,8 +274,9 @@ void show_registers(struct pt_regs *regs) | |||
268 | regs->esi, regs->edi, regs->ebp, esp); | 274 | regs->esi, regs->edi, regs->ebp, esp); |
269 | printk(KERN_EMERG "ds: %04x es: %04x ss: %04x\n", | 275 | printk(KERN_EMERG "ds: %04x es: %04x ss: %04x\n", |
270 | regs->xds & 0xffff, regs->xes & 0xffff, ss); | 276 | regs->xds & 0xffff, regs->xes & 0xffff, ss); |
271 | printk(KERN_EMERG "Process %s (pid: %d, threadinfo=%p task=%p)", | 277 | printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", |
272 | current->comm, current->pid, current_thread_info(), current); | 278 | TASK_COMM_LEN, current->comm, current->pid, |
279 | current_thread_info(), current, current->thread_info); | ||
273 | /* | 280 | /* |
274 | * When in-kernel, we also print out the stack and code at the | 281 | * When in-kernel, we also print out the stack and code at the |
275 | * time of the fault.. | 282 | * time of the fault.. |
diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c index 4cf981d70f45..6979297ce278 100644 --- a/arch/i386/lib/usercopy.c +++ b/arch/i386/lib/usercopy.c | |||
@@ -425,15 +425,121 @@ __copy_user_zeroing_intel(void *to, const void __user *from, unsigned long size) | |||
425 | : "eax", "edx", "memory"); | 425 | : "eax", "edx", "memory"); |
426 | return size; | 426 | return size; |
427 | } | 427 | } |
428 | |||
429 | /* | ||
430 | * Non Temporal Hint version of __copy_user_zeroing_intel. It is cache aware. | ||
431 | * hyoshiok@miraclelinux.com | ||
432 | */ | ||
433 | |||
434 | static unsigned long __copy_user_zeroing_intel_nocache(void *to, | ||
435 | const void __user *from, unsigned long size) | ||
436 | { | ||
437 | int d0, d1; | ||
438 | |||
439 | __asm__ __volatile__( | ||
440 | " .align 2,0x90\n" | ||
441 | "0: movl 32(%4), %%eax\n" | ||
442 | " cmpl $67, %0\n" | ||
443 | " jbe 2f\n" | ||
444 | "1: movl 64(%4), %%eax\n" | ||
445 | " .align 2,0x90\n" | ||
446 | "2: movl 0(%4), %%eax\n" | ||
447 | "21: movl 4(%4), %%edx\n" | ||
448 | " movnti %%eax, 0(%3)\n" | ||
449 | " movnti %%edx, 4(%3)\n" | ||
450 | "3: movl 8(%4), %%eax\n" | ||
451 | "31: movl 12(%4),%%edx\n" | ||
452 | " movnti %%eax, 8(%3)\n" | ||
453 | " movnti %%edx, 12(%3)\n" | ||
454 | "4: movl 16(%4), %%eax\n" | ||
455 | "41: movl 20(%4), %%edx\n" | ||
456 | " movnti %%eax, 16(%3)\n" | ||
457 | " movnti %%edx, 20(%3)\n" | ||
458 | "10: movl 24(%4), %%eax\n" | ||
459 | "51: movl 28(%4), %%edx\n" | ||
460 | " movnti %%eax, 24(%3)\n" | ||
461 | " movnti %%edx, 28(%3)\n" | ||
462 | "11: movl 32(%4), %%eax\n" | ||
463 | "61: movl 36(%4), %%edx\n" | ||
464 | " movnti %%eax, 32(%3)\n" | ||
465 | " movnti %%edx, 36(%3)\n" | ||
466 | "12: movl 40(%4), %%eax\n" | ||
467 | "71: movl 44(%4), %%edx\n" | ||
468 | " movnti %%eax, 40(%3)\n" | ||
469 | " movnti %%edx, 44(%3)\n" | ||
470 | "13: movl 48(%4), %%eax\n" | ||
471 | "81: movl 52(%4), %%edx\n" | ||
472 | " movnti %%eax, 48(%3)\n" | ||
473 | " movnti %%edx, 52(%3)\n" | ||
474 | "14: movl 56(%4), %%eax\n" | ||
475 | "91: movl 60(%4), %%edx\n" | ||
476 | " movnti %%eax, 56(%3)\n" | ||
477 | " movnti %%edx, 60(%3)\n" | ||
478 | " addl $-64, %0\n" | ||
479 | " addl $64, %4\n" | ||
480 | " addl $64, %3\n" | ||
481 | " cmpl $63, %0\n" | ||
482 | " ja 0b\n" | ||
483 | " sfence \n" | ||
484 | "5: movl %0, %%eax\n" | ||
485 | " shrl $2, %0\n" | ||
486 | " andl $3, %%eax\n" | ||
487 | " cld\n" | ||
488 | "6: rep; movsl\n" | ||
489 | " movl %%eax,%0\n" | ||
490 | "7: rep; movsb\n" | ||
491 | "8:\n" | ||
492 | ".section .fixup,\"ax\"\n" | ||
493 | "9: lea 0(%%eax,%0,4),%0\n" | ||
494 | "16: pushl %0\n" | ||
495 | " pushl %%eax\n" | ||
496 | " xorl %%eax,%%eax\n" | ||
497 | " rep; stosb\n" | ||
498 | " popl %%eax\n" | ||
499 | " popl %0\n" | ||
500 | " jmp 8b\n" | ||
501 | ".previous\n" | ||
502 | ".section __ex_table,\"a\"\n" | ||
503 | " .align 4\n" | ||
504 | " .long 0b,16b\n" | ||
505 | " .long 1b,16b\n" | ||
506 | " .long 2b,16b\n" | ||
507 | " .long 21b,16b\n" | ||
508 | " .long 3b,16b\n" | ||
509 | " .long 31b,16b\n" | ||
510 | " .long 4b,16b\n" | ||
511 | " .long 41b,16b\n" | ||
512 | " .long 10b,16b\n" | ||
513 | " .long 51b,16b\n" | ||
514 | " .long 11b,16b\n" | ||
515 | " .long 61b,16b\n" | ||
516 | " .long 12b,16b\n" | ||
517 | " .long 71b,16b\n" | ||
518 | " .long 13b,16b\n" | ||
519 | " .long 81b,16b\n" | ||
520 | " .long 14b,16b\n" | ||
521 | " .long 91b,16b\n" | ||
522 | " .long 6b,9b\n" | ||
523 | " .long 7b,16b\n" | ||
524 | ".previous" | ||
525 | : "=&c"(size), "=&D" (d0), "=&S" (d1) | ||
526 | : "1"(to), "2"(from), "0"(size) | ||
527 | : "eax", "edx", "memory"); | ||
528 | return size; | ||
529 | } | ||
530 | |||
428 | #else | 531 | #else |
532 | |||
429 | /* | 533 | /* |
430 | * Leave these declared but undefined. They should not be any references to | 534 | * Leave these declared but undefined. They should not be any references to |
431 | * them | 535 | * them |
432 | */ | 536 | */ |
433 | unsigned long | 537 | unsigned long __copy_user_zeroing_intel(void *to, const void __user *from, |
434 | __copy_user_zeroing_intel(void *to, const void __user *from, unsigned long size); | 538 | unsigned long size); |
435 | unsigned long | 539 | unsigned long __copy_user_intel(void __user *to, const void *from, |
436 | __copy_user_intel(void __user *to, const void *from, unsigned long size); | 540 | unsigned long size); |
541 | unsigned long __copy_user_zeroing_intel_nocache(void *to, | ||
542 | const void __user *from, unsigned long size); | ||
437 | #endif /* CONFIG_X86_INTEL_USERCOPY */ | 543 | #endif /* CONFIG_X86_INTEL_USERCOPY */ |
438 | 544 | ||
439 | /* Generic arbitrary sized copy. */ | 545 | /* Generic arbitrary sized copy. */ |
@@ -515,8 +621,8 @@ do { \ | |||
515 | : "memory"); \ | 621 | : "memory"); \ |
516 | } while (0) | 622 | } while (0) |
517 | 623 | ||
518 | 624 | unsigned long __copy_to_user_ll(void __user *to, const void *from, | |
519 | unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long n) | 625 | unsigned long n) |
520 | { | 626 | { |
521 | BUG_ON((long) n < 0); | 627 | BUG_ON((long) n < 0); |
522 | #ifndef CONFIG_X86_WP_WORKS_OK | 628 | #ifndef CONFIG_X86_WP_WORKS_OK |
@@ -576,8 +682,8 @@ survive: | |||
576 | } | 682 | } |
577 | EXPORT_SYMBOL(__copy_to_user_ll); | 683 | EXPORT_SYMBOL(__copy_to_user_ll); |
578 | 684 | ||
579 | unsigned long | 685 | unsigned long __copy_from_user_ll(void *to, const void __user *from, |
580 | __copy_from_user_ll(void *to, const void __user *from, unsigned long n) | 686 | unsigned long n) |
581 | { | 687 | { |
582 | BUG_ON((long)n < 0); | 688 | BUG_ON((long)n < 0); |
583 | if (movsl_is_ok(to, from, n)) | 689 | if (movsl_is_ok(to, from, n)) |
@@ -588,6 +694,21 @@ __copy_from_user_ll(void *to, const void __user *from, unsigned long n) | |||
588 | } | 694 | } |
589 | EXPORT_SYMBOL(__copy_from_user_ll); | 695 | EXPORT_SYMBOL(__copy_from_user_ll); |
590 | 696 | ||
697 | unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, | ||
698 | unsigned long n) | ||
699 | { | ||
700 | BUG_ON((long)n < 0); | ||
701 | #ifdef CONFIG_X86_INTEL_USERCOPY | ||
702 | if ( n > 64 && cpu_has_xmm2) | ||
703 | n = __copy_user_zeroing_intel_nocache(to, from, n); | ||
704 | else | ||
705 | __copy_user_zeroing(to, from, n); | ||
706 | #else | ||
707 | __copy_user_zeroing(to, from, n); | ||
708 | #endif | ||
709 | return n; | ||
710 | } | ||
711 | |||
591 | /** | 712 | /** |
592 | * copy_to_user: - Copy a block of data into user space. | 713 | * copy_to_user: - Copy a block of data into user space. |
593 | * @to: Destination address, in user space. | 714 | * @to: Destination address, in user space. |
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index 7f0fcf219a26..bd6fe96cc16d 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c | |||
@@ -77,12 +77,15 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs, | |||
77 | unsigned seg = regs->xcs & 0xffff; | 77 | unsigned seg = regs->xcs & 0xffff; |
78 | u32 seg_ar, seg_limit, base, *desc; | 78 | u32 seg_ar, seg_limit, base, *desc; |
79 | 79 | ||
80 | /* Unlikely, but must come before segment checks. */ | ||
81 | if (unlikely(regs->eflags & VM_MASK)) { | ||
82 | base = seg << 4; | ||
83 | *eip_limit = base + 0xffff; | ||
84 | return base + (eip & 0xffff); | ||
85 | } | ||
86 | |||
80 | /* The standard kernel/user address space limit. */ | 87 | /* The standard kernel/user address space limit. */ |
81 | *eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg; | 88 | *eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg; |
82 | |||
83 | /* Unlikely, but must come before segment checks. */ | ||
84 | if (unlikely((regs->eflags & VM_MASK) != 0)) | ||
85 | return eip + (seg << 4); | ||
86 | 89 | ||
87 | /* By far the most common cases. */ | 90 | /* By far the most common cases. */ |
88 | if (likely(seg == __USER_CS || seg == __KERNEL_CS)) | 91 | if (likely(seg == __USER_CS || seg == __KERNEL_CS)) |
@@ -380,12 +383,12 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, | |||
380 | goto bad_area; | 383 | goto bad_area; |
381 | if (error_code & 4) { | 384 | if (error_code & 4) { |
382 | /* | 385 | /* |
383 | * accessing the stack below %esp is always a bug. | 386 | * Accessing the stack below %esp is always a bug. |
384 | * The "+ 32" is there due to some instructions (like | 387 | * The large cushion allows instructions like enter |
385 | * pusha) doing post-decrement on the stack and that | 388 | * and pusha to work. ("enter $65535,$31" pushes |
386 | * doesn't show up until later.. | 389 | * 32 pointers and then decrements %esp by 65535.) |
387 | */ | 390 | */ |
388 | if (address + 32 < regs->esp) | 391 | if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp) |
389 | goto bad_area; | 392 | goto bad_area; |
390 | } | 393 | } |
391 | if (expand_stack(vma, address)) | 394 | if (expand_stack(vma, address)) |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 3df1371d4520..bf19513f0cea 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/efi.h> | 29 | #include <linux/efi.h> |
30 | #include <linux/memory_hotplug.h> | 30 | #include <linux/memory_hotplug.h> |
31 | #include <linux/initrd.h> | 31 | #include <linux/initrd.h> |
32 | #include <linux/cpumask.h> | ||
32 | 33 | ||
33 | #include <asm/processor.h> | 34 | #include <asm/processor.h> |
34 | #include <asm/system.h> | 35 | #include <asm/system.h> |
@@ -384,7 +385,7 @@ static void __init pagetable_init (void) | |||
384 | #endif | 385 | #endif |
385 | } | 386 | } |
386 | 387 | ||
387 | #ifdef CONFIG_SOFTWARE_SUSPEND | 388 | #if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP) |
388 | /* | 389 | /* |
389 | * Swap suspend & friends need this for resume because things like the intel-agp | 390 | * Swap suspend & friends need this for resume because things like the intel-agp |
390 | * driver might have split up a kernel 4MB mapping. | 391 | * driver might have split up a kernel 4MB mapping. |
diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index 92c3d9f0e731..0887b34bc59b 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c | |||
@@ -209,19 +209,19 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot) | |||
209 | } | 209 | } |
210 | 210 | ||
211 | void global_flush_tlb(void) | 211 | void global_flush_tlb(void) |
212 | { | 212 | { |
213 | LIST_HEAD(l); | 213 | struct list_head l; |
214 | struct page *pg, *next; | 214 | struct page *pg, *next; |
215 | 215 | ||
216 | BUG_ON(irqs_disabled()); | 216 | BUG_ON(irqs_disabled()); |
217 | 217 | ||
218 | spin_lock_irq(&cpa_lock); | 218 | spin_lock_irq(&cpa_lock); |
219 | list_splice_init(&df_list, &l); | 219 | list_replace_init(&df_list, &l); |
220 | spin_unlock_irq(&cpa_lock); | 220 | spin_unlock_irq(&cpa_lock); |
221 | flush_map(); | 221 | flush_map(); |
222 | list_for_each_entry_safe(pg, next, &l, lru) | 222 | list_for_each_entry_safe(pg, next, &l, lru) |
223 | __free_page(pg); | 223 | __free_page(pg); |
224 | } | 224 | } |
225 | 225 | ||
226 | #ifdef CONFIG_DEBUG_PAGEALLOC | 226 | #ifdef CONFIG_DEBUG_PAGEALLOC |
227 | void kernel_map_pages(struct page *page, int numpages, int enable) | 227 | void kernel_map_pages(struct page *page, int numpages, int enable) |
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index dbece776c5b2..c624b61e1104 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -288,6 +288,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
288 | 288 | ||
289 | void pcibios_disable_device (struct pci_dev *dev) | 289 | void pcibios_disable_device (struct pci_dev *dev) |
290 | { | 290 | { |
291 | pcibios_disable_resources(dev); | ||
291 | if (pcibios_disable_irq) | 292 | if (pcibios_disable_irq) |
292 | pcibios_disable_irq(dev); | 293 | pcibios_disable_irq(dev); |
293 | } | 294 | } |
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index ed2c8c899bd3..7852827a599b 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c | |||
@@ -242,6 +242,15 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) | |||
242 | return 0; | 242 | return 0; |
243 | } | 243 | } |
244 | 244 | ||
245 | void pcibios_disable_resources(struct pci_dev *dev) | ||
246 | { | ||
247 | u16 cmd; | ||
248 | |||
249 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
250 | cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); | ||
251 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
252 | } | ||
253 | |||
245 | /* | 254 | /* |
246 | * If we set up a device for bus mastering, we need to check the latency | 255 | * If we set up a device for bus mastering, we need to check the latency |
247 | * timer as certain crappy BIOSes forget to set it properly. | 256 | * timer as certain crappy BIOSes forget to set it properly. |
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 06dab00aaadc..8ce69508f3c7 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -198,14 +198,14 @@ static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigne | |||
198 | */ | 198 | */ |
199 | static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | 199 | static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq) |
200 | { | 200 | { |
201 | static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; | 201 | static const unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; |
202 | 202 | ||
203 | return irqmap[read_config_nybble(router, 0x48, pirq-1)]; | 203 | return irqmap[read_config_nybble(router, 0x48, pirq-1)]; |
204 | } | 204 | } |
205 | 205 | ||
206 | static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | 206 | static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
207 | { | 207 | { |
208 | static unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; | 208 | static const unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; |
209 | unsigned int val = irqmap[irq]; | 209 | unsigned int val = irqmap[irq]; |
210 | 210 | ||
211 | if (val) { | 211 | if (val) { |
@@ -256,13 +256,13 @@ static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i | |||
256 | */ | 256 | */ |
257 | static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | 257 | static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) |
258 | { | 258 | { |
259 | static unsigned int pirqmap[4] = { 3, 2, 5, 1 }; | 259 | static const unsigned int pirqmap[4] = { 3, 2, 5, 1 }; |
260 | return read_config_nybble(router, 0x55, pirqmap[pirq-1]); | 260 | return read_config_nybble(router, 0x55, pirqmap[pirq-1]); |
261 | } | 261 | } |
262 | 262 | ||
263 | static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | 263 | static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
264 | { | 264 | { |
265 | static unsigned int pirqmap[4] = { 3, 2, 5, 1 }; | 265 | static const unsigned int pirqmap[4] = { 3, 2, 5, 1 }; |
266 | write_config_nybble(router, 0x55, pirqmap[pirq-1], irq); | 266 | write_config_nybble(router, 0x55, pirqmap[pirq-1], irq); |
267 | return 1; | 267 | return 1; |
268 | } | 268 | } |
@@ -274,13 +274,13 @@ static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq | |||
274 | */ | 274 | */ |
275 | static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | 275 | static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq) |
276 | { | 276 | { |
277 | static unsigned char pirqmap[4] = { 1, 0, 2, 3 }; | 277 | static const unsigned char pirqmap[4] = { 1, 0, 2, 3 }; |
278 | return read_config_nybble(router,0x43, pirqmap[pirq-1]); | 278 | return read_config_nybble(router,0x43, pirqmap[pirq-1]); |
279 | } | 279 | } |
280 | 280 | ||
281 | static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | 281 | static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
282 | { | 282 | { |
283 | static unsigned char pirqmap[4] = { 1, 0, 2, 3 }; | 283 | static const unsigned char pirqmap[4] = { 1, 0, 2, 3 }; |
284 | write_config_nybble(router, 0x43, pirqmap[pirq-1], irq); | 284 | write_config_nybble(router, 0x43, pirqmap[pirq-1], irq); |
285 | return 1; | 285 | return 1; |
286 | } | 286 | } |
@@ -505,7 +505,7 @@ static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, | |||
505 | 505 | ||
506 | static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | 506 | static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) |
507 | { | 507 | { |
508 | static struct pci_device_id pirq_440gx[] = { | 508 | static struct pci_device_id __initdata pirq_440gx[] = { |
509 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) }, | 509 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) }, |
510 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) }, | 510 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) }, |
511 | { }, | 511 | { }, |
@@ -880,6 +880,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
880 | ((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask)) ) { | 880 | ((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask)) ) { |
881 | DBG(" -> got IRQ %d\n", irq); | 881 | DBG(" -> got IRQ %d\n", irq); |
882 | msg = "Found"; | 882 | msg = "Found"; |
883 | eisa_set_level_irq(irq); | ||
883 | } else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { | 884 | } else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { |
884 | DBG(" -> assigning IRQ %d", newirq); | 885 | DBG(" -> assigning IRQ %d", newirq); |
885 | if (r->set(pirq_router_dev, dev, pirq, newirq)) { | 886 | if (r->set(pirq_router_dev, dev, pirq, newirq)) { |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 6b1ea0c9a570..e545b0992c48 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -15,7 +15,9 @@ | |||
15 | #include <asm/e820.h> | 15 | #include <asm/e820.h> |
16 | #include "pci.h" | 16 | #include "pci.h" |
17 | 17 | ||
18 | #define MMCONFIG_APER_SIZE (256*1024*1024) | 18 | /* aperture is up to 256MB but BIOS may reserve less */ |
19 | #define MMCONFIG_APER_MIN (2 * 1024*1024) | ||
20 | #define MMCONFIG_APER_MAX (256 * 1024*1024) | ||
19 | 21 | ||
20 | /* Assume systems with more busses have correct MCFG */ | 22 | /* Assume systems with more busses have correct MCFG */ |
21 | #define MAX_CHECK_BUS 16 | 23 | #define MAX_CHECK_BUS 16 |
@@ -197,9 +199,10 @@ void __init pci_mmcfg_init(void) | |||
197 | return; | 199 | return; |
198 | 200 | ||
199 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | 201 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, |
200 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE, | 202 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, |
201 | E820_RESERVED)) { | 203 | E820_RESERVED)) { |
202 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n"); | 204 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", |
205 | pci_mmcfg_config[0].base_address); | ||
203 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | 206 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); |
204 | return; | 207 | return; |
205 | } | 208 | } |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index 12035e29108b..12bf3d8dda29 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -35,6 +35,7 @@ extern unsigned int pcibios_max_latency; | |||
35 | 35 | ||
36 | void pcibios_resource_survey(void); | 36 | void pcibios_resource_survey(void); |
37 | int pcibios_enable_resources(struct pci_dev *, int); | 37 | int pcibios_enable_resources(struct pci_dev *, int); |
38 | void pcibios_disable_resources(struct pci_dev *); | ||
38 | 39 | ||
39 | /* pci-pc.c */ | 40 | /* pci-pc.c */ |
40 | 41 | ||
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c index 79b2370c7fac..e6517915fe3e 100644 --- a/arch/i386/power/cpu.c +++ b/arch/i386/power/cpu.c | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/suspend.h> | 12 | #include <linux/suspend.h> |
13 | #include <asm/mtrr.h> | ||
14 | #include <asm/mce.h> | ||
13 | 15 | ||
14 | static struct saved_context saved_context; | 16 | static struct saved_context saved_context; |
15 | 17 | ||