Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6.23
[sfrench/cifs-2.6.git] / drivers / acpi / processor_idle.c
index bb5d23be42607fe4ebb3c91c6dd118287242131b..a8634a0655fca429b0a52f3c43b8d57a8ccc3095 100644 (file)
@@ -490,7 +490,17 @@ static void acpi_processor_idle(void)
 
        case ACPI_STATE_C3:
 
-               if (pr->flags.bm_check) {
+               /*
+                * disable bus master
+                * bm_check implies we need ARB_DIS
+                * !bm_check implies we need cache flush
+                * bm_control implies whether we can do ARB_DIS
+                *
+                * That leaves a case where bm_check is set and bm_control is
+                * not set. In that case we cannot do much, we enter C3
+                * without doing anything.
+                */
+               if (pr->flags.bm_check && pr->flags.bm_control) {
                        if (atomic_inc_return(&c3_cpu_count) ==
                            num_online_cpus()) {
                                /*
@@ -499,7 +509,7 @@ static void acpi_processor_idle(void)
                                 */
                                acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
                        }
-               } else {
+               } else if (!pr->flags.bm_check) {
                        /* SMP with no shared cache... Invalidate cache  */
                        ACPI_FLUSH_CPU_CACHE();
                }
@@ -511,7 +521,7 @@ static void acpi_processor_idle(void)
                acpi_cstate_enter(cx);
                /* Get end time (ticks) */
                t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-               if (pr->flags.bm_check) {
+               if (pr->flags.bm_check && pr->flags.bm_control) {
                        /* Enable bus master arbitration */
                        atomic_dec(&c3_cpu_count);
                        acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
@@ -959,11 +969,17 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
        }
 
        if (pr->flags.bm_check) {
-               /* bus mastering control is necessary */
                if (!pr->flags.bm_control) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                         "C3 support requires bus mastering control\n"));
-                       return;
+                       if (pr->flags.has_cst != 1) {
+                               /* bus mastering control is necessary */
+                               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                       "C3 support requires BM control\n"));
+                               return;
+                       } else {
+                               /* Here we enter C3 without bus mastering */
+                               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                       "C3 support without BM control\n"));
+                       }
                }
        } else {
                /*