diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-22 22:43:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-22 22:43:02 -0400 |
commit | 37c70d0d09747a958ec50aeb11ed1bf896da028c (patch) | |
tree | 5f026a3cfc7e4d4b11ca8cf7c787325bfb96e4e0 /drivers/acpi/processor_idle.c | |
parent | 7f52a3afc4c02db75b3953fcbbb980abc86873a2 (diff) | |
parent | cddece4beccaa72dcb57d64a7f1e496b2e61a16b (diff) |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6:
ACPI: IA64: fix %ll build warnings
ACPI: IA64: fix allnoconfig build
ACPI: Only use IPI on known broken machines (AMD, Dothan/BaniasPentium M)
ACPI: ibm-acpi: allow module to load when acpi notifiers can't be set (v2)
ACPI: parse 2nd MADT by default
ACPICA: revert "acpi_serialize" changes
sony-laptop: MAINTAINERS fix entry, add L: and W:
ACPI: resolve HP nx6125 S3 immediate wakeup regression
ACPI: Add support to parse 2nd MADT
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r-- | drivers/acpi/processor_idle.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 60773005b8af..562124ed785e 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -89,6 +89,12 @@ module_param(nocst, uint, 0000); | |||
89 | static unsigned int bm_history __read_mostly = | 89 | static unsigned int bm_history __read_mostly = |
90 | (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1)); | 90 | (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1)); |
91 | module_param(bm_history, uint, 0644); | 91 | module_param(bm_history, uint, 0644); |
92 | |||
93 | static unsigned use_ipi = 2; | ||
94 | module_param(use_ipi, uint, 0644); | ||
95 | MODULE_PARM_DESC(use_ipi, "IPI (vs. LAPIC) irqs for not waking up from C2/C3" | ||
96 | " machines. 0=apic, 1=ipi, 2=auto\n"); | ||
97 | |||
92 | /* -------------------------------------------------------------------------- | 98 | /* -------------------------------------------------------------------------- |
93 | Power Management | 99 | Power Management |
94 | -------------------------------------------------------------------------- */ | 100 | -------------------------------------------------------------------------- */ |
@@ -260,9 +266,8 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) | |||
260 | 266 | ||
261 | /* | 267 | /* |
262 | * Some BIOS implementations switch to C3 in the published C2 state. | 268 | * Some BIOS implementations switch to C3 in the published C2 state. |
263 | * This seems to be a common problem on AMD boxen, but other vendors | 269 | * This seems to be a common problem on AMD boxen and Intel Dothan/Banias |
264 | * are affected too. We pick the most conservative approach: we assume | 270 | * Pentium M machines. |
265 | * that the local APIC stops in both C2 and C3. | ||
266 | */ | 271 | */ |
267 | static void acpi_timer_check_state(int state, struct acpi_processor *pr, | 272 | static void acpi_timer_check_state(int state, struct acpi_processor *pr, |
268 | struct acpi_processor_cx *cx) | 273 | struct acpi_processor_cx *cx) |
@@ -276,8 +281,17 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr, | |||
276 | if (pwr->timer_broadcast_on_state < state) | 281 | if (pwr->timer_broadcast_on_state < state) |
277 | return; | 282 | return; |
278 | 283 | ||
279 | if (cx->type >= ACPI_STATE_C2) | 284 | if (cx->type >= ACPI_STATE_C2) { |
280 | pr->power.timer_broadcast_on_state = state; | 285 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) |
286 | pr->power.timer_broadcast_on_state = state; | ||
287 | else if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | ||
288 | boot_cpu_data.x86 == 6) && | ||
289 | (boot_cpu_data.x86_model == 13 || | ||
290 | boot_cpu_data.x86_model == 9)) | ||
291 | { | ||
292 | pr->power.timer_broadcast_on_state = state; | ||
293 | } | ||
294 | } | ||
281 | } | 295 | } |
282 | 296 | ||
283 | static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) | 297 | static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) |
@@ -292,10 +306,16 @@ static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) | |||
292 | #else | 306 | #else |
293 | cpumask_t mask = cpumask_of_cpu(pr->id); | 307 | cpumask_t mask = cpumask_of_cpu(pr->id); |
294 | 308 | ||
295 | if (pr->power.timer_broadcast_on_state < INT_MAX) | 309 | if (use_ipi == 0) |
296 | on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1); | 310 | on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1); |
297 | else | 311 | else if (use_ipi == 1) |
298 | on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1); | 312 | on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1); |
313 | else { | ||
314 | if (pr->power.timer_broadcast_on_state < INT_MAX) | ||
315 | on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1); | ||
316 | else | ||
317 | on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1); | ||
318 | } | ||
299 | #endif | 319 | #endif |
300 | } | 320 | } |
301 | 321 | ||
@@ -1013,13 +1033,13 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) | |||
1013 | 1033 | ||
1014 | case ACPI_STATE_C2: | 1034 | case ACPI_STATE_C2: |
1015 | acpi_processor_power_verify_c2(cx); | 1035 | acpi_processor_power_verify_c2(cx); |
1016 | if (cx->valid) | 1036 | if (cx->valid && use_ipi != 0 && use_ipi != 1) |
1017 | acpi_timer_check_state(i, pr, cx); | 1037 | acpi_timer_check_state(i, pr, cx); |
1018 | break; | 1038 | break; |
1019 | 1039 | ||
1020 | case ACPI_STATE_C3: | 1040 | case ACPI_STATE_C3: |
1021 | acpi_processor_power_verify_c3(pr, cx); | 1041 | acpi_processor_power_verify_c3(pr, cx); |
1022 | if (cx->valid) | 1042 | if (cx->valid && use_ipi != 0 && use_ipi != 1) |
1023 | acpi_timer_check_state(i, pr, cx); | 1043 | acpi_timer_check_state(i, pr, cx); |
1024 | break; | 1044 | break; |
1025 | } | 1045 | } |