diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
-rw-r--r-- | arch/ia64/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/process.c | 17 | ||||
-rw-r--r-- | drivers/acpi/processor_idle.c | 22 | ||||
-rw-r--r-- | include/asm-ia64/processor.h | 1 | ||||
-rw-r--r-- | include/asm-x86/processor.h | 1 |
6 files changed, 45 insertions, 2 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 312fe77764a4..65db7f4711aa 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -818,7 +818,7 @@ and is between 256 and 4096 characters. It is defined in the file | |||
818 | See Documentation/ide/ide.txt. | 818 | See Documentation/ide/ide.txt. |
819 | 819 | ||
820 | idle= [X86] | 820 | idle= [X86] |
821 | Format: idle=poll or idle=mwait | 821 | Format: idle=poll or idle=mwait, idle=halt |
822 | Poll forces a polling idle loop that can slightly improves the performance | 822 | Poll forces a polling idle loop that can slightly improves the performance |
823 | of waking up a idle CPU, but will use a lot of power and make the system | 823 | of waking up a idle CPU, but will use a lot of power and make the system |
824 | run hot. Not recommended. | 824 | run hot. Not recommended. |
@@ -826,6 +826,8 @@ and is between 256 and 4096 characters. It is defined in the file | |||
826 | to not use it because it doesn't save as much power as a normal idle | 826 | to not use it because it doesn't save as much power as a normal idle |
827 | loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same | 827 | loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same |
828 | as idle=poll. | 828 | as idle=poll. |
829 | idle=halt. Halt is forced to be used for CPU idle. | ||
830 | In such case C2/C3 won't be used again. | ||
829 | 831 | ||
830 | ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem | 832 | ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem |
831 | Claim all unknown PCI IDE storage controllers. | 833 | Claim all unknown PCI IDE storage controllers. |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index fabaf08d9a69..612b3c4a0603 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -55,6 +55,8 @@ void (*ia64_mark_idle)(int); | |||
55 | 55 | ||
56 | unsigned long boot_option_idle_override = 0; | 56 | unsigned long boot_option_idle_override = 0; |
57 | EXPORT_SYMBOL(boot_option_idle_override); | 57 | EXPORT_SYMBOL(boot_option_idle_override); |
58 | unsigned long idle_halt; | ||
59 | EXPORT_SYMBOL(idle_halt); | ||
58 | 60 | ||
59 | void | 61 | void |
60 | ia64_do_show_stack (struct unw_frame_info *info, void *arg) | 62 | ia64_do_show_stack (struct unw_frame_info *info, void *arg) |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 7dceea947232..7fc729498760 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -7,6 +7,10 @@ | |||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/pm.h> | 8 | #include <linux/pm.h> |
9 | #include <linux/clockchips.h> | 9 | #include <linux/clockchips.h> |
10 | #include <asm/system.h> | ||
11 | |||
12 | unsigned long idle_halt; | ||
13 | EXPORT_SYMBOL(idle_halt); | ||
10 | 14 | ||
11 | struct kmem_cache *task_xstate_cachep; | 15 | struct kmem_cache *task_xstate_cachep; |
12 | 16 | ||
@@ -325,7 +329,18 @@ static int __init idle_setup(char *str) | |||
325 | pm_idle = poll_idle; | 329 | pm_idle = poll_idle; |
326 | } else if (!strcmp(str, "mwait")) | 330 | } else if (!strcmp(str, "mwait")) |
327 | force_mwait = 1; | 331 | force_mwait = 1; |
328 | else | 332 | else if (!strcmp(str, "halt")) { |
333 | /* | ||
334 | * When the boot option of idle=halt is added, halt is | ||
335 | * forced to be used for CPU idle. In such case CPU C2/C3 | ||
336 | * won't be used again. | ||
337 | * To continue to load the CPU idle driver, don't touch | ||
338 | * the boot_option_idle_override. | ||
339 | */ | ||
340 | pm_idle = default_idle; | ||
341 | idle_halt = 1; | ||
342 | return 0; | ||
343 | } else | ||
329 | return -1; | 344 | return -1; |
330 | 345 | ||
331 | boot_option_idle_override = 1; | 346 | boot_option_idle_override = 1; |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 0fc310e7dfd6..c75c7ace8c13 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/pm_qos_params.h> | 41 | #include <linux/pm_qos_params.h> |
42 | #include <linux/clockchips.h> | 42 | #include <linux/clockchips.h> |
43 | #include <linux/cpuidle.h> | 43 | #include <linux/cpuidle.h> |
44 | #include <linux/cpuidle.h> | ||
44 | 45 | ||
45 | /* | 46 | /* |
46 | * Include the apic definitions for x86 to have the APIC timer related defines | 47 | * Include the apic definitions for x86 to have the APIC timer related defines |
@@ -57,6 +58,7 @@ | |||
57 | 58 | ||
58 | #include <acpi/acpi_bus.h> | 59 | #include <acpi/acpi_bus.h> |
59 | #include <acpi/processor.h> | 60 | #include <acpi/processor.h> |
61 | #include <asm/processor.h> | ||
60 | 62 | ||
61 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | 63 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 |
62 | #define ACPI_PROCESSOR_CLASS "processor" | 64 | #define ACPI_PROCESSOR_CLASS "processor" |
@@ -955,6 +957,17 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) | |||
955 | } else { | 957 | } else { |
956 | continue; | 958 | continue; |
957 | } | 959 | } |
960 | if (cx.type == ACPI_STATE_C1 && idle_halt) { | ||
961 | /* | ||
962 | * In most cases the C1 space_id obtained from | ||
963 | * _CST object is FIXED_HARDWARE access mode. | ||
964 | * But when the option of idle=halt is added, | ||
965 | * the entry_method type should be changed from | ||
966 | * CSTATE_FFH to CSTATE_HALT. | ||
967 | */ | ||
968 | cx.entry_method = ACPI_CSTATE_HALT; | ||
969 | snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT"); | ||
970 | } | ||
958 | } else { | 971 | } else { |
959 | snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x", | 972 | snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x", |
960 | cx.address); | 973 | cx.address); |
@@ -1780,6 +1793,15 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1780 | return 0; | 1793 | return 0; |
1781 | 1794 | ||
1782 | if (!first_run) { | 1795 | if (!first_run) { |
1796 | if (idle_halt) { | ||
1797 | /* | ||
1798 | * When the boot option of "idle=halt" is added, halt | ||
1799 | * is used for CPU IDLE. | ||
1800 | * In such case C2/C3 is meaningless. So the max_cstate | ||
1801 | * is set to one. | ||
1802 | */ | ||
1803 | max_cstate = 1; | ||
1804 | } | ||
1783 | dmi_check_system(processor_power_dmi_table); | 1805 | dmi_check_system(processor_power_dmi_table); |
1784 | max_cstate = acpi_processor_cstate_check(max_cstate); | 1806 | max_cstate = acpi_processor_cstate_check(max_cstate); |
1785 | if (max_cstate < ACPI_C_STATES_MAX) | 1807 | if (max_cstate < ACPI_C_STATES_MAX) |
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 6aff126fc07e..f36e28a5f61e 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h | |||
@@ -763,6 +763,7 @@ prefetchw (const void *x) | |||
763 | #define spin_lock_prefetch(x) prefetchw(x) | 763 | #define spin_lock_prefetch(x) prefetchw(x) |
764 | 764 | ||
765 | extern unsigned long boot_option_idle_override; | 765 | extern unsigned long boot_option_idle_override; |
766 | extern unsigned long idle_halt; | ||
766 | 767 | ||
767 | #endif /* !__ASSEMBLY__ */ | 768 | #endif /* !__ASSEMBLY__ */ |
768 | 769 | ||
diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 7f7382704592..bc221623248e 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h | |||
@@ -727,6 +727,7 @@ extern int force_mwait; | |||
727 | extern void select_idle_routine(const struct cpuinfo_x86 *c); | 727 | extern void select_idle_routine(const struct cpuinfo_x86 *c); |
728 | 728 | ||
729 | extern unsigned long boot_option_idle_override; | 729 | extern unsigned long boot_option_idle_override; |
730 | extern unsigned long idle_halt; | ||
730 | 731 | ||
731 | extern void enable_sep_cpu(void); | 732 | extern void enable_sep_cpu(void); |
732 | extern int sysenter_setup(void); | 733 | extern int sysenter_setup(void); |