void (*__read_mostly lapic_timer_off)(void);
void (*__read_mostly lapic_timer_on)(void);
+bool_t lapic_timer_init(void)
+{
+ if ( boot_cpu_has(X86_FEATURE_ARAT) )
+ {
+ lapic_timer_off = lapic_timer_nop;
+ lapic_timer_on = lapic_timer_nop;
+ }
+ else if ( hpet_broadcast_is_available() )
+ {
+ lapic_timer_off = hpet_broadcast_enter;
+ lapic_timer_on = hpet_broadcast_exit;
+ }
+ else if ( pit_broadcast_is_available() )
+ {
+ lapic_timer_off = pit_broadcast_enter;
+ lapic_timer_on = pit_broadcast_exit;
+ }
+ else
+ return 0;
+
+ return 1;
+}
+
static uint64_t (*__read_mostly tick_to_ns)(uint64_t) = acpi_pm_tick_to_ns;
void (*__read_mostly pm_idle_save)(void);
if ( local_apic_timer_c2_ok )
break;
case ACPI_STATE_C3:
- if ( boot_cpu_has(X86_FEATURE_ARAT) )
- {
- lapic_timer_off = lapic_timer_nop;
- lapic_timer_on = lapic_timer_nop;
- }
- else if ( hpet_broadcast_is_available() )
- {
- lapic_timer_off = hpet_broadcast_enter;
- lapic_timer_on = hpet_broadcast_exit;
- }
- else if ( pit_broadcast_is_available() )
- {
- lapic_timer_off = pit_broadcast_enter;
- lapic_timer_on = pit_broadcast_exit;
- }
- else
- {
+ if ( !lapic_timer_init() )
return -EINVAL;
- }
/* All the logic here assumes flags.bm_check is same across all CPUs */
if ( bm_check_flag == -1 )
#include <xen/softirq.h>
#include <xen/trace.h>
#include <asm/cpuidle.h>
+#include <asm/hpet.h>
#include <asm/mwait.h>
#include <asm/msr.h>
#include <acpi/cpufreq/cpufreq.h>
return -ENODEV;
err = mwait_idle_probe();
+ if (!err) {
+ if (!boot_cpu_has(X86_FEATURE_ARAT))
+ hpet_broadcast_init();
+ if (!lapic_timer_init())
+ err = -EINVAL;
+ }
if (!err) {
nfb->notifier_call = mwait_idle_cpu_init;
mwait_idle_cpu_init(nfb, CPU_UP_PREPARE, NULL);