diff options
author | Zhao Yakui <yakui.zhao@intel.com> | 2007-11-29 03:22:43 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-12-01 23:27:15 -0500 |
commit | 357dc4c3f13cb5c1e3b40a09cbe6ff1b0df2c7c3 (patch) | |
tree | 794d39137bae2073423f93b3b14717824138290c /drivers/acpi | |
parent | f79f06ab9f86d7203006d2ec8992ac80df36a34e (diff) |
ACPI: Delete the IRQ operation in throttling controll via PTC
The IRQ operation(enable/disable) should be avoided when throttling is
controlled via PTC method. It is replaced by the migration of task.
This fixes an oops on T61 -- a regression due to
f79f06ab9f86 b/c FixedHW support tried to read remote MSR with interrupts disabled.
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/processor_throttling.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index c26c61fb36c3..6742d7bc4777 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/sched.h> | ||
32 | #include <linux/cpufreq.h> | 33 | #include <linux/cpufreq.h> |
33 | #include <linux/proc_fs.h> | 34 | #include <linux/proc_fs.h> |
34 | #include <linux/seq_file.h> | 35 | #include <linux/seq_file.h> |
@@ -413,7 +414,7 @@ static int acpi_throttling_rdmsr(struct acpi_processor *pr, | |||
413 | } else { | 414 | } else { |
414 | msr_low = 0; | 415 | msr_low = 0; |
415 | msr_high = 0; | 416 | msr_high = 0; |
416 | rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, | 417 | rdmsr_safe(MSR_IA32_THERM_CONTROL, |
417 | (u32 *)&msr_low , (u32 *) &msr_high); | 418 | (u32 *)&msr_low , (u32 *) &msr_high); |
418 | msr = (msr_high << 32) | msr_low; | 419 | msr = (msr_high << 32) | msr_low; |
419 | *value = (acpi_integer) msr; | 420 | *value = (acpi_integer) msr; |
@@ -438,7 +439,7 @@ static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) | |||
438 | "HARDWARE addr space,NOT supported yet\n"); | 439 | "HARDWARE addr space,NOT supported yet\n"); |
439 | } else { | 440 | } else { |
440 | msr = value; | 441 | msr = value; |
441 | wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, | 442 | wrmsr_safe(MSR_IA32_THERM_CONTROL, |
442 | msr & 0xffffffff, msr >> 32); | 443 | msr & 0xffffffff, msr >> 32); |
443 | ret = 0; | 444 | ret = 0; |
444 | } | 445 | } |
@@ -572,21 +573,32 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) | |||
572 | return -ENODEV; | 573 | return -ENODEV; |
573 | 574 | ||
574 | pr->throttling.state = 0; | 575 | pr->throttling.state = 0; |
575 | local_irq_disable(); | 576 | |
576 | value = 0; | 577 | value = 0; |
577 | ret = acpi_read_throttling_status(pr, &value); | 578 | ret = acpi_read_throttling_status(pr, &value); |
578 | if (ret >= 0) { | 579 | if (ret >= 0) { |
579 | state = acpi_get_throttling_state(pr, value); | 580 | state = acpi_get_throttling_state(pr, value); |
580 | pr->throttling.state = state; | 581 | pr->throttling.state = state; |
581 | } | 582 | } |
582 | local_irq_enable(); | ||
583 | 583 | ||
584 | return 0; | 584 | return 0; |
585 | } | 585 | } |
586 | 586 | ||
587 | static int acpi_processor_get_throttling(struct acpi_processor *pr) | 587 | static int acpi_processor_get_throttling(struct acpi_processor *pr) |
588 | { | 588 | { |
589 | return pr->throttling.acpi_processor_get_throttling(pr); | 589 | cpumask_t saved_mask; |
590 | int ret; | ||
591 | |||
592 | /* | ||
593 | * Migrate task to the cpu pointed by pr. | ||
594 | */ | ||
595 | saved_mask = current->cpus_allowed; | ||
596 | set_cpus_allowed(current, cpumask_of_cpu(pr->id)); | ||
597 | ret = pr->throttling.acpi_processor_get_throttling(pr); | ||
598 | /* restore the previous state */ | ||
599 | set_cpus_allowed(current, saved_mask); | ||
600 | |||
601 | return ret; | ||
590 | } | 602 | } |
591 | 603 | ||
592 | static int acpi_processor_get_fadt_info(struct acpi_processor *pr) | 604 | static int acpi_processor_get_fadt_info(struct acpi_processor *pr) |
@@ -717,21 +729,29 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, | |||
717 | if (state < pr->throttling_platform_limit) | 729 | if (state < pr->throttling_platform_limit) |
718 | return -EPERM; | 730 | return -EPERM; |
719 | 731 | ||
720 | local_irq_disable(); | ||
721 | value = 0; | 732 | value = 0; |
722 | ret = acpi_get_throttling_value(pr, state, &value); | 733 | ret = acpi_get_throttling_value(pr, state, &value); |
723 | if (ret >= 0) { | 734 | if (ret >= 0) { |
724 | acpi_write_throttling_state(pr, value); | 735 | acpi_write_throttling_state(pr, value); |
725 | pr->throttling.state = state; | 736 | pr->throttling.state = state; |
726 | } | 737 | } |
727 | local_irq_enable(); | ||
728 | 738 | ||
729 | return 0; | 739 | return 0; |
730 | } | 740 | } |
731 | 741 | ||
732 | int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | 742 | int acpi_processor_set_throttling(struct acpi_processor *pr, int state) |
733 | { | 743 | { |
734 | return pr->throttling.acpi_processor_set_throttling(pr, state); | 744 | cpumask_t saved_mask; |
745 | int ret; | ||
746 | /* | ||
747 | * Migrate task to the cpu pointed by pr. | ||
748 | */ | ||
749 | saved_mask = current->cpus_allowed; | ||
750 | set_cpus_allowed(current, cpumask_of_cpu(pr->id)); | ||
751 | ret = pr->throttling.acpi_processor_set_throttling(pr, state); | ||
752 | /* restore the previous state */ | ||
753 | set_cpus_allowed(current, saved_mask); | ||
754 | return ret; | ||
735 | } | 755 | } |
736 | 756 | ||
737 | int acpi_processor_get_throttling_info(struct acpi_processor *pr) | 757 | int acpi_processor_get_throttling_info(struct acpi_processor *pr) |