From: Keir Fraser Date: Thu, 12 Jun 2008 16:17:44 +0000 (+0100) Subject: x86: Do not use HPET in Cx state management since dom0 may need RTC X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14192^2~81 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0c0556ff7917c6a7f57c45e3cb3d6561c7899a06;p=xen.git x86: Do not use HPET in Cx state management since dom0 may need RTC IRQ routing. This makes C3 unusable for now. Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c index 28e3e658ff..9517bd21ad 100644 --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -724,8 +724,6 @@ static void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flag static int check_cx(struct acpi_processor_power *power, xen_processor_cx_t *cx) { static int bm_check_flag; - if ( cx == NULL ) - return -EINVAL; switch ( cx->reg.space_id ) { @@ -743,7 +741,7 @@ static int check_cx(struct acpi_processor_power *power, xen_processor_cx_t *cx) /* assume all logical cpu has the same support for mwait */ if ( acpi_processor_ffh_cstate_probe(cx) ) - return -EFAULT; + return -EINVAL; } break; @@ -753,6 +751,10 @@ static int check_cx(struct acpi_processor_power *power, xen_processor_cx_t *cx) if ( cx->type == ACPI_STATE_C3 ) { + /* We must be able to use HPET in place of LAPIC timers. */ + if ( !hpet_broadcast_is_available() ) + return -EINVAL; + /* All the logic here assumes flags.bm_check is same across all CPUs */ if ( !bm_check_flag ) { @@ -774,7 +776,7 @@ static int check_cx(struct acpi_processor_power *power, xen_processor_cx_t *cx) /* bus mastering control is necessary */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "C3 support requires BM control\n")); - return -1; + return -EINVAL; } else { @@ -795,7 +797,7 @@ static int check_cx(struct acpi_processor_power *power, xen_processor_cx_t *cx) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cache invalidation should work properly" " for C3 to be enabled on SMP systems\n")); - return -1; + return -EINVAL; } acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); } @@ -804,14 +806,14 @@ static int check_cx(struct acpi_processor_power *power, xen_processor_cx_t *cx) return 0; } -static int set_cx(struct acpi_processor_power *acpi_power, - xen_processor_cx_t *xen_cx) +static void set_cx( + struct acpi_processor_power *acpi_power, + xen_processor_cx_t *xen_cx) { struct acpi_processor_cx *cx; - /* skip unsupported acpi cstate */ - if ( check_cx(acpi_power, xen_cx) ) - return -EFAULT; + if ( check_cx(acpi_power, xen_cx) != 0 ) + return; cx = &acpi_power->states[xen_cx->type]; if ( !cx->valid ) @@ -825,8 +827,6 @@ static int set_cx(struct acpi_processor_power *acpi_power, cx->power = xen_cx->power; cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); - - return 0; } int get_cpu_id(u8 acpi_id) diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index 5c4b53ea75..3e2e95423e 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -235,6 +235,11 @@ void hpet_broadcast_exit(void) reprogram_timer(per_cpu(timer_deadline, cpu)); } +int hpet_broadcast_is_available(void) +{ + return (hpet_event.event_handler == handle_hpet_broadcast); +} + int hpet_legacy_irq_tick(void) { if ( !hpet_event.event_handler ) diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 2a3c85b05e..fe5bef24ac 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -1012,7 +1012,7 @@ static int disable_pit_irq(void) * If we do not rely on PIT CH0 then we can use HPET for one-shot * timer emulation when entering deep C states. */ - hpet_broadcast_init(); + /*hpet_broadcast_init(); XXX dom0 may rely on RTC interrupt delivery */ } return 0; diff --git a/xen/include/asm-x86/hpet.h b/xen/include/asm-x86/hpet.h index 1f4681a373..b63f56805d 100644 --- a/xen/include/asm-x86/hpet.h +++ b/xen/include/asm-x86/hpet.h @@ -68,5 +68,6 @@ int hpet_legacy_irq_tick(void); void hpet_broadcast_init(void); void hpet_broadcast_enter(void); void hpet_broadcast_exit(void); +int hpet_broadcast_is_available(void); #endif /* __X86_HPET_H__ */