]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/acpi/processor_idle.c
IB/mlx4: Include linux/mutex.h from mlx4_ib.h
[linux-2.6-omap-h63xx.git] / drivers / acpi / processor_idle.c
index 562124ed785ec20923da69e014c0b0ac89e9bf75..80ffc782991631492d08c2dea2837972698e5193 100644 (file)
 #include <asm/apic.h>
 #endif
 
-/*
- * Include the apic definitions for x86 to have the APIC timer related defines
- * available also for UP (on SMP it gets magically included via linux/smp.h).
- */
-#ifdef CONFIG_X86
-#include <asm/apic.h>
-#endif
-
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
@@ -89,12 +81,6 @@ module_param(nocst, uint, 0000);
 static unsigned int bm_history __read_mostly =
     (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
 module_param(bm_history, uint, 0644);
-
-static unsigned use_ipi = 2;
-module_param(use_ipi, uint, 0644);
-MODULE_PARM_DESC(use_ipi, "IPI (vs. LAPIC) irqs for not waking up from C2/C3"
-                " machines. 0=apic, 1=ipi, 2=auto\n");
-
 /* --------------------------------------------------------------------------
                                 Power Management
    -------------------------------------------------------------------------- */
@@ -266,13 +252,15 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
 
 /*
  * Some BIOS implementations switch to C3 in the published C2 state.
- * This seems to be a common problem on AMD boxen and Intel Dothan/Banias
- * Pentium M machines.
+ * This seems to be a common problem on AMD boxen, but other vendors
+ * are affected too. We pick the most conservative approach: we assume
+ * that the local APIC stops in both C2 and C3.
  */
 static void acpi_timer_check_state(int state, struct acpi_processor *pr,
                                   struct acpi_processor_cx *cx)
 {
        struct acpi_processor_power *pwr = &pr->power;
+       u8 type = local_apic_timer_c2_ok ? ACPI_STATE_C3 : ACPI_STATE_C2;
 
        /*
         * Check, if one of the previous states already marked the lapic
@@ -281,17 +269,8 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,
        if (pwr->timer_broadcast_on_state < state)
                return;
 
-       if (cx->type >= ACPI_STATE_C2) {
-               if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
-                       pr->power.timer_broadcast_on_state = state;
-               else if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
-                         boot_cpu_data.x86 == 6) &&
-                        (boot_cpu_data.x86_model == 13 ||
-                         boot_cpu_data.x86_model == 9))
-               {
-                       pr->power.timer_broadcast_on_state = state;
-               }
-       }
+       if (cx->type >= type)
+               pr->power.timer_broadcast_on_state = state;
 }
 
 static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
@@ -306,16 +285,10 @@ static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
 #else
        cpumask_t mask = cpumask_of_cpu(pr->id);
 
-       if (use_ipi == 0)
+       if (pr->power.timer_broadcast_on_state < INT_MAX)
                on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1);
-       else if (use_ipi == 1)
+       else
                on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
-       else {
-               if (pr->power.timer_broadcast_on_state < INT_MAX)
-                       on_each_cpu(switch_APIC_timer_to_ipi, &mask, 1, 1);
-               else
-                       on_each_cpu(switch_ipi_to_APIC_timer, &mask, 1, 1);
-       }
 #endif
 }
 
@@ -359,16 +332,18 @@ static void acpi_processor_idle(void)
        int sleep_ticks = 0;
        u32 t1, t2 = 0;
 
-       pr = processors[smp_processor_id()];
-       if (!pr)
-               return;
-
        /*
         * Interrupts must be disabled during bus mastering calculations and
         * for C2/C3 transitions.
         */
        local_irq_disable();
 
+       pr = processors[smp_processor_id()];
+       if (!pr) {
+               local_irq_enable();
+               return;
+       }
+
        /*
         * Check whether we truly need to go idle, or should
         * reschedule:
@@ -502,7 +477,7 @@ static void acpi_processor_idle(void)
 
 #ifdef CONFIG_GENERIC_TIME
                /* TSC halts in C2, so notify users */
-               mark_tsc_unstable();
+               mark_tsc_unstable("possible TSC halt in C2");
 #endif
                /* Re-enable interrupts */
                local_irq_enable();
@@ -544,7 +519,7 @@ static void acpi_processor_idle(void)
 
 #ifdef CONFIG_GENERIC_TIME
                /* TSC halts in C3, so notify users */
-               mark_tsc_unstable();
+               mark_tsc_unstable("TSC halts in C3");
 #endif
                /* Re-enable interrupts */
                local_irq_enable();
@@ -1033,13 +1008,13 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
 
                case ACPI_STATE_C2:
                        acpi_processor_power_verify_c2(cx);
-                       if (cx->valid && use_ipi != 0 && use_ipi != 1)
+                       if (cx->valid)
                                acpi_timer_check_state(i, pr, cx);
                        break;
 
                case ACPI_STATE_C3:
                        acpi_processor_power_verify_c3(pr, cx);
-                       if (cx->valid && use_ipi != 0 && use_ipi != 1)
+                       if (cx->valid)
                                acpi_timer_check_state(i, pr, cx);
                        break;
                }