x86: Do not use HPET in Cx state management since dom0 may need RTC
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 12 Jun 2008 16:17:44 +0000 (17:17 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 12 Jun 2008 16:17:44 +0000 (17:17 +0100)
IRQ routing. This makes C3 unusable for now.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/acpi/cpu_idle.c
xen/arch/x86/hpet.c
xen/arch/x86/time.c
xen/include/asm-x86/hpet.h

index 28e3e658ff04d56ce3b41903c9e7dbc31228f441..9517bd21adb61706f3286710557108552774c1d5 100644 (file)
@@ -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)
index 5c4b53ea75bf34f728839ee20953c4f0801ead29..3e2e95423e7a4d41231fab80a62570932f1d6b18 100644 (file)
@@ -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 )
index 2a3c85b05e33080e62c25b377d1a97c343788070..fe5bef24ac4823c8a5dc4e8d4b31bdca73d78055 100644 (file)
@@ -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;
index 1f4681a3735044698b10b9668dd1614983f245b6..b63f56805d82341aa4d143f921f00add6381243d 100644 (file)
@@ -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__ */