Merge branches 'release', 'acpica', 'bugzilla-10224', 'bugzilla-9772', 'bugzilla...
[pandora-kernel.git] / drivers / acpi / processor_idle.c
index e8e2d88..55d69dc 100644 (file)
@@ -418,13 +418,12 @@ static void acpi_processor_idle(void)
 
        cx = pr->power.state;
        if (!cx || acpi_idle_suspend) {
-               if (pm_idle_save)
-                       pm_idle_save();
-               else
+               if (pm_idle_save) {
+                       pm_idle_save(); /* enables IRQs */
+               } else {
                        acpi_safe_halt();
-
-               if (irqs_disabled())
                        local_irq_enable();
+               }
 
                return;
        }
@@ -520,10 +519,12 @@ static void acpi_processor_idle(void)
                 * Use the appropriate idle routine, the one that would
                 * be used without acpi C-states.
                 */
-               if (pm_idle_save)
-                       pm_idle_save();
-               else
+               if (pm_idle_save) {
+                       pm_idle_save(); /* enables IRQs */
+               } else {
                        acpi_safe_halt();
+                       local_irq_enable();
+               }
 
                /*
                 * TBD: Can't get time duration while in C1, as resumes
@@ -534,8 +535,6 @@ static void acpi_processor_idle(void)
                 *       skew otherwise.
                 */
                sleep_ticks = 0xFFFFFFFF;
-               if (irqs_disabled())
-                       local_irq_enable();
 
                break;
 
@@ -848,6 +847,7 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr)
                /* all processors need to support C1 */
                pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
                pr->power.states[ACPI_STATE_C1].valid = 1;
+               pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT;
        }
        /* the C0 state only exists as a filler in our array */
        pr->power.states[ACPI_STATE_C0].valid = 1;
@@ -960,6 +960,9 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
                                 cx.address);
                }
 
+               if (cx.type == ACPI_STATE_C1) {
+                       cx.valid = 1;
+               }
 
                obj = &(element->package.elements[2]);
                if (obj->type != ACPI_TYPE_INTEGER)
@@ -1295,6 +1298,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
 {
        int result = 0;
 
+       if (boot_option_idle_override)
+               return 0;
 
        if (!pr)
                return -EINVAL;
@@ -1487,7 +1492,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
                return 0;
        }
 
-       acpi_unlazy_tlb(smp_processor_id());
        /*
         * Must be done before busmaster disable as we might need to
         * access HPET !
@@ -1577,6 +1581,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
                return 0;
        }
 
+       acpi_unlazy_tlb(smp_processor_id());
+
        /* Tell the scheduler that we are going deep-idle: */
        sched_clock_idle_sleep_event();
        /*
@@ -1692,7 +1698,9 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
                switch (cx->type) {
                        case ACPI_STATE_C1:
                        state->flags |= CPUIDLE_FLAG_SHALLOW;
-                       state->flags |= CPUIDLE_FLAG_TIME_VALID;
+                       if (cx->entry_method == ACPI_CSTATE_FFH)
+                               state->flags |= CPUIDLE_FLAG_TIME_VALID;
+
                        state->enter = acpi_idle_enter_c1;
                        dev->safe_state = state;
                        break;
@@ -1731,6 +1739,9 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
 {
        int ret;
 
+       if (boot_option_idle_override)
+               return 0;
+
        if (!pr)
                return -EINVAL;
 
@@ -1761,6 +1772,8 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
        struct proc_dir_entry *entry = NULL;
        unsigned int i;
 
+       if (boot_option_idle_override)
+               return 0;
 
        if (!first_run) {
                dmi_check_system(processor_power_dmi_table);
@@ -1796,7 +1809,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
         * Note that we use previously set idle handler will be used on
         * platforms that only support C1.
         */
-       if ((pr->flags.power) && (!boot_option_idle_override)) {
+       if (pr->flags.power) {
 #ifdef CONFIG_CPU_IDLE
                acpi_processor_setup_cpuidle(pr);
                pr->power.dev.cpu = pr->id;
@@ -1836,8 +1849,11 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
 int acpi_processor_power_exit(struct acpi_processor *pr,
                              struct acpi_device *device)
 {
+       if (boot_option_idle_override)
+               return 0;
+
 #ifdef CONFIG_CPU_IDLE
-       if ((pr->flags.power) && (!boot_option_idle_override))
+       if (pr->flags.power)
                cpuidle_unregister_device(&pr->power.dev);
 #endif
        pr->flags.power_setup_done = 0;