Commit 714d8ac4 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] C1 fixes when processor driver is loaded

honor "halt=" cmdline parameter
use monitor/mwait when available
http://bugzilla.kernel.org/show_bug.cgi?id=2280Signed-off-by: default avatarVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent bcaf14d8
...@@ -57,6 +57,9 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); ...@@ -57,6 +57,9 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
int hlt_counter; int hlt_counter;
unsigned long boot_option_idle_override = 0;
EXPORT_SYMBOL(boot_option_idle_override);
/* /*
* Return saved PC of a blocked thread. * Return saved PC of a blocked thread.
*/ */
...@@ -211,6 +214,7 @@ static int __init idle_setup (char *str) ...@@ -211,6 +214,7 @@ static int __init idle_setup (char *str)
pm_idle = default_idle; pm_idle = default_idle;
} }
boot_option_idle_override = 1;
return 1; return 1;
} }
......
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
void (*ia64_mark_idle)(int); void (*ia64_mark_idle)(int);
unsigned long boot_option_idle_override = 0;
EXPORT_SYMBOL(boot_option_idle_override);
void void
ia64_do_show_stack (struct unw_frame_info *info, void *arg) ia64_do_show_stack (struct unw_frame_info *info, void *arg)
......
...@@ -54,6 +54,9 @@ unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; ...@@ -54,6 +54,9 @@ unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
atomic_t hlt_counter = ATOMIC_INIT(0); atomic_t hlt_counter = ATOMIC_INIT(0);
unsigned long boot_option_idle_override = 0;
EXPORT_SYMBOL(boot_option_idle_override);
/* /*
* Powermanagement idle function, if any.. * Powermanagement idle function, if any..
*/ */
...@@ -192,6 +195,7 @@ static int __init idle_setup (char *str) ...@@ -192,6 +195,7 @@ static int __init idle_setup (char *str)
pm_idle = poll_idle; pm_idle = poll_idle;
} }
boot_option_idle_override = 1;
return 1; return 1;
} }
......
...@@ -411,8 +411,15 @@ acpi_processor_idle (void) ...@@ -411,8 +411,15 @@ acpi_processor_idle (void)
switch (pr->power.state) { switch (pr->power.state) {
case ACPI_STATE_C1: case ACPI_STATE_C1:
/* Invoke C1. */ /*
safe_halt(); * Invoke C1.
* Use the appropriate idle routine, the one that would
* be used without acpi C-states.
*/
if (pm_idle_save)
pm_idle_save();
else
safe_halt();
/* /*
* TBD: Can't get time duration while in C1, as resumes * TBD: Can't get time duration while in C1, as resumes
* go to an ISR rather than here. Need to instrument * go to an ISR rather than here. Need to instrument
...@@ -2388,22 +2395,28 @@ acpi_processor_add ( ...@@ -2388,22 +2395,28 @@ acpi_processor_add (
/* /*
* Install the idle handler if processor power management is supported. * Install the idle handler if processor power management is supported.
* Note that the default idle handler (default_idle) will be used on * Note that we use previously set idle handler will be used on
* platforms that only support C1. * platforms that only support C1.
*/ */
if ((pr->id == 0) && (pr->flags.power)) { if ((pr->flags.power) && (!boot_option_idle_override)) {
pm_idle_save = pm_idle; printk(KERN_INFO PREFIX "%s [%s] (supports",
pm_idle = acpi_processor_idle; acpi_device_name(device), acpi_device_bid(device));
for (i = 1; i < ACPI_C_STATE_COUNT; i++)
if (pr->power.states[i].valid)
printk(" C%d", i);
printk(")\n");
if (pr->id == 0) {
pm_idle_save = pm_idle;
pm_idle = acpi_processor_idle;
}
} }
printk(KERN_INFO PREFIX "%s [%s] (supports", if (pr->flags.throttling) {
acpi_device_name(device), acpi_device_bid(device)); printk(KERN_INFO PREFIX "%s [%s] (supports",
for (i=1; i<ACPI_C_STATE_COUNT; i++) acpi_device_name(device), acpi_device_bid(device));
if (pr->power.states[i].valid) printk(" %d throttling states", pr->throttling.state_count);
printk(" C%d", i); printk(")\n");
if (pr->flags.throttling) }
printk(", %d throttling states", pr->throttling.state_count);
printk(")\n");
end: end:
if (result) { if (result) {
......
...@@ -650,4 +650,6 @@ extern void select_idle_routine(const struct cpuinfo_x86 *c); ...@@ -650,4 +650,6 @@ extern void select_idle_routine(const struct cpuinfo_x86 *c);
#define ARCH_HAS_SCHED_WAKE_IDLE #define ARCH_HAS_SCHED_WAKE_IDLE
#endif #endif
extern unsigned long boot_option_idle_override;
#endif /* __ASM_I386_PROCESSOR_H */ #endif /* __ASM_I386_PROCESSOR_H */
...@@ -688,6 +688,8 @@ prefetchw (const void *x) ...@@ -688,6 +688,8 @@ prefetchw (const void *x)
#define spin_lock_prefetch(x) prefetchw(x) #define spin_lock_prefetch(x) prefetchw(x)
extern unsigned long boot_option_idle_override;
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* _ASM_IA64_PROCESSOR_H */ #endif /* _ASM_IA64_PROCESSOR_H */
...@@ -461,4 +461,6 @@ static inline void __mwait(unsigned long eax, unsigned long ecx) ...@@ -461,4 +461,6 @@ static inline void __mwait(unsigned long eax, unsigned long ecx)
#define ARCH_HAS_SCHED_WAKE_IDLE #define ARCH_HAS_SCHED_WAKE_IDLE
#endif #endif
extern unsigned long boot_option_idle_override;
#endif /* __ASM_X86_64_PROCESSOR_H */ #endif /* __ASM_X86_64_PROCESSOR_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment