include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / acpi / processor_idle.c
index f7ca8c5..5939e7f 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
+#include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/acpi.h>
@@ -60,6 +61,8 @@
 #include <acpi/processor.h>
 #include <asm/processor.h>
 
+#define PREFIX "ACPI: "
+
 #define ACPI_PROCESSOR_CLASS            "processor"
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME("processor_idle");
@@ -108,6 +111,14 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
          DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
          DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
         (void *)2},
+       { set_max_cstate, "Pavilion zv5000", {
+         DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+         DMI_MATCH(DMI_PRODUCT_NAME,"Pavilion zv5000 (DS502A#ABA)")},
+        (void *)1},
+       { set_max_cstate, "Asus L8400B", {
+         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
+         DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")},
+        (void *)1},
        {},
 };
 
@@ -139,7 +150,7 @@ static void acpi_safe_halt(void)
  * 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,
+static void lapic_timer_check_state(int state, struct acpi_processor *pr,
                                   struct acpi_processor_cx *cx)
 {
        struct acpi_processor_power *pwr = &pr->power;
@@ -148,6 +159,9 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,
        if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
                return;
 
+       if (boot_cpu_has(X86_FEATURE_AMDC1E))
+               type = ACPI_STATE_C1;
+
        /*
         * Check, if one of the previous states already marked the lapic
         * unstable
@@ -159,8 +173,9 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,
                pr->power.timer_broadcast_on_state = state;
 }
 
-static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
+static void __lapic_timer_propagate_broadcast(void *arg)
 {
+       struct acpi_processor *pr = (struct acpi_processor *) arg;
        unsigned long reason;
 
        reason = pr->power.timer_broadcast_on_state < INT_MAX ?
@@ -169,8 +184,14 @@ static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
        clockevents_notify(reason, &pr->id);
 }
 
+static void lapic_timer_propagate_broadcast(struct acpi_processor *pr)
+{
+       smp_call_function_single(pr->id, __lapic_timer_propagate_broadcast,
+                                (void *)pr, 1);
+}
+
 /* Power(C) State timer broadcast control */
-static void acpi_state_timer_broadcast(struct acpi_processor *pr,
+static void lapic_timer_state_broadcast(struct acpi_processor *pr,
                                       struct acpi_processor_cx *cx,
                                       int broadcast)
 {
@@ -187,10 +208,10 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr,
 
 #else
 
-static void acpi_timer_check_state(int state, struct acpi_processor *pr,
+static void lapic_timer_check_state(int state, struct acpi_processor *pr,
                                   struct acpi_processor_cx *cstate) { }
-static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { }
-static void acpi_state_timer_broadcast(struct acpi_processor *pr,
+static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { }
+static void lapic_timer_state_broadcast(struct acpi_processor *pr,
                                       struct acpi_processor_cx *cx,
                                       int broadcast)
 {
@@ -202,21 +223,44 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr,
  * Suspend / resume control
  */
 static int acpi_idle_suspend;
+static u32 saved_bm_rld;
+
+static void acpi_idle_bm_rld_save(void)
+{
+       acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld);
+}
+static void acpi_idle_bm_rld_restore(void)
+{
+       u32 resumed_bm_rld;
+
+       acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld);
+
+       if (resumed_bm_rld != saved_bm_rld)
+               acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld);
+}
 
 int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
 {
+       if (acpi_idle_suspend == 1)
+               return 0;
+
+       acpi_idle_bm_rld_save();
        acpi_idle_suspend = 1;
        return 0;
 }
 
 int acpi_processor_resume(struct acpi_device * device)
 {
+       if (acpi_idle_suspend == 0)
+               return 0;
+
+       acpi_idle_bm_rld_restore();
        acpi_idle_suspend = 0;
        return 0;
 }
 
 #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
-static int tsc_halts_in_c(int state)
+static void tsc_check_state(int state)
 {
        switch (boot_cpu_data.x86_vendor) {
        case X86_VENDOR_AMD:
@@ -226,13 +270,17 @@ static int tsc_halts_in_c(int state)
                 * C/P/S0/S1 states when this bit is set.
                 */
                if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
-                       return 0;
+                       return;
 
                /*FALL THROUGH*/
        default:
-               return state > ACPI_STATE_C1;
+               /* TSC could halt in idle, so notify users */
+               if (state > ACPI_STATE_C1)
+                       mark_tsc_unstable("TSC halts in idle");
        }
 }
+#else
+static void tsc_check_state(int state) { return; }
 #endif
 
 static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
@@ -266,6 +314,28 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
        pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.C2latency;
        pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.C3latency;
 
+       /*
+        * FADT specified C2 latency must be less than or equal to
+        * 100 microseconds.
+        */
+       if (acpi_gbl_FADT.C2latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                       "C2 latency too large [%d]\n", acpi_gbl_FADT.C2latency));
+               /* invalidate C2 */
+               pr->power.states[ACPI_STATE_C2].address = 0;
+       }
+
+       /*
+        * FADT supplied C3 latency must be less than or equal to
+        * 1000 microseconds.
+        */
+       if (acpi_gbl_FADT.C3latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                       "C3 latency too large [%d]\n", acpi_gbl_FADT.C3latency));
+               /* invalidate C3 */
+               pr->power.states[ACPI_STATE_C3].address = 0;
+       }
+
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                          "lvl2[0x%08x] lvl3[0x%08x]\n",
                          pr->power.states[ACPI_STATE_C2].address,
@@ -291,7 +361,7 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr)
 static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
 {
        acpi_status status = 0;
-       acpi_integer count;
+       u64 count;
        int current_count;
        int i;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -455,53 +525,17 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
        return status;
 }
 
-static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
-{
-
-       if (!cx->address)
-               return;
-
-       /*
-        * C2 latency must be less than or equal to 100
-        * microseconds.
-        */
-       else if (cx->latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "latency too large [%d]\n", cx->latency));
-               return;
-       }
-
-       /*
-        * Otherwise we've met all of our C2 requirements.
-        * Normalize the C2 latency to expidite policy
-        */
-       cx->valid = 1;
-
-       cx->latency_ticks = cx->latency;
-
-       return;
-}
-
 static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
                                           struct acpi_processor_cx *cx)
 {
-       static int bm_check_flag;
+       static int bm_check_flag = -1;
+       static int bm_control_flag = -1;
 
 
        if (!cx->address)
                return;
 
        /*
-        * C3 latency must be less than or equal to 1000
-        * microseconds.
-        */
-       else if (cx->latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "latency too large [%d]\n", cx->latency));
-               return;
-       }
-
-       /*
         * PIIX4 Erratum #18: We don't support C3 when Type-F (fast)
         * DMA transfers are used by any ISA device to avoid livelock.
         * Note that we could disable Type-F DMA (as recommended by
@@ -515,12 +549,14 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
        }
 
        /* All the logic here assumes flags.bm_check is same across all CPUs */
-       if (!bm_check_flag) {
+       if (bm_check_flag == -1) {
                /* Determine whether bm_check is needed based on CPU  */
                acpi_processor_power_init_bm_check(&(pr->flags), pr->id);
                bm_check_flag = pr->flags.bm_check;
+               bm_control_flag = pr->flags.bm_control;
        } else {
                pr->flags.bm_check = bm_check_flag;
+               pr->flags.bm_control = bm_control_flag;
        }
 
        if (pr->flags.bm_check) {
@@ -578,37 +614,34 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
 
        pr->power.timer_broadcast_on_state = INT_MAX;
 
-       for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
+       for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
                struct acpi_processor_cx *cx = &pr->power.states[i];
 
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
-               /* TSC could halt in idle, so notify users */
-               if (tsc_halts_in_c(cx->type))
-                       mark_tsc_unstable("TSC halts in idle");;
-#endif
                switch (cx->type) {
                case ACPI_STATE_C1:
                        cx->valid = 1;
                        break;
 
                case ACPI_STATE_C2:
-                       acpi_processor_power_verify_c2(cx);
-                       if (cx->valid)
-                               acpi_timer_check_state(i, pr, cx);
+                       if (!cx->address)
+                               break;
+                       cx->valid = 1; 
+                       cx->latency_ticks = cx->latency; /* Normalize latency */
                        break;
 
                case ACPI_STATE_C3:
                        acpi_processor_power_verify_c3(pr, cx);
-                       if (cx->valid)
-                               acpi_timer_check_state(i, pr, cx);
                        break;
                }
+               if (!cx->valid)
+                       continue;
 
-               if (cx->valid)
-                       working++;
+               lapic_timer_check_state(i, pr, cx);
+               tsc_check_state(cx->type);
+               working++;
        }
 
-       acpi_propagate_timer_broadcast(pr);
+       lapic_timer_propagate_broadcast(pr);
 
        return (working);
 }
@@ -651,6 +684,7 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
        return 0;
 }
 
+#ifdef CONFIG_ACPI_PROCFS
 static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
 {
        struct acpi_processor *pr = seq->private;
@@ -730,7 +764,7 @@ static const struct file_operations acpi_processor_power_fops = {
        .llseek = seq_lseek,
        .release = single_release,
 };
-
+#endif
 
 /**
  * acpi_idle_bm_check - checks if bus master activity was detected
@@ -806,11 +840,12 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
 
        /* Do not access any ACPI IO ports in suspend path */
        if (acpi_idle_suspend) {
-               acpi_safe_halt();
                local_irq_enable();
+               cpu_relax();
                return 0;
        }
 
+       lapic_timer_state_broadcast(pr, cx, 1);
        kt1 = ktime_get_real();
        acpi_idle_do_entry(cx);
        kt2 = ktime_get_real();
@@ -818,6 +853,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
 
        local_irq_enable();
        cx->usage++;
+       lapic_timer_state_broadcast(pr, cx, 0);
 
        return idle_time;
 }
@@ -845,12 +881,14 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
                return(acpi_idle_enter_c1(dev, state));
 
        local_irq_disable();
-       current_thread_info()->status &= ~TS_POLLING;
-       /*
-        * TS_POLLING-cleared state must be visible before we test
-        * NEED_RESCHED:
-        */
-       smp_mb();
+       if (cx->entry_method != ACPI_CSTATE_FFH) {
+               current_thread_info()->status &= ~TS_POLLING;
+               /*
+                * TS_POLLING-cleared state must be visible before we test
+                * NEED_RESCHED:
+                */
+               smp_mb();
+       }
 
        if (unlikely(need_resched())) {
                current_thread_info()->status |= TS_POLLING;
@@ -862,7 +900,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
         * Must be done before busmaster disable as we might need to
         * access HPET !
         */
-       acpi_state_timer_broadcast(pr, cx, 1);
+       lapic_timer_state_broadcast(pr, cx, 1);
 
        if (cx->type == ACPI_STATE_C3)
                ACPI_FLUSH_CPU_CACHE();
@@ -884,7 +922,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
 
        cx->usage++;
 
-       acpi_state_timer_broadcast(pr, cx, 0);
+       lapic_timer_state_broadcast(pr, cx, 0);
        cx->time += sleep_ticks;
        return idle_time;
 }
@@ -930,12 +968,14 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
        }
 
        local_irq_disable();
-       current_thread_info()->status &= ~TS_POLLING;
-       /*
-        * TS_POLLING-cleared state must be visible before we test
-        * NEED_RESCHED:
-        */
-       smp_mb();
+       if (cx->entry_method != ACPI_CSTATE_FFH) {
+               current_thread_info()->status &= ~TS_POLLING;
+               /*
+                * TS_POLLING-cleared state must be visible before we test
+                * NEED_RESCHED:
+                */
+               smp_mb();
+       }
 
        if (unlikely(need_resched())) {
                current_thread_info()->status |= TS_POLLING;
@@ -951,7 +991,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
         * Must be done before busmaster disable as we might need to
         * access HPET !
         */
-       acpi_state_timer_broadcast(pr, cx, 1);
+       lapic_timer_state_broadcast(pr, cx, 1);
 
        kt1 = ktime_get_real();
        /*
@@ -996,7 +1036,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
 
        cx->usage++;
 
-       acpi_state_timer_broadcast(pr, cx, 0);
+       lapic_timer_state_broadcast(pr, cx, 0);
        cx->time += sleep_ticks;
        return idle_time;
 }
@@ -1129,8 +1169,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
 {
        acpi_status status = 0;
        static int first_run;
+#ifdef CONFIG_ACPI_PROCFS
        struct proc_dir_entry *entry = NULL;
-       unsigned int i;
+#endif
 
        if (boot_option_idle_override)
                return 0;
@@ -1178,15 +1219,8 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
                acpi_processor_setup_cpuidle(pr);
                if (cpuidle_register_device(&pr->power.dev))
                        return -EIO;
-
-               printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
-               for (i = 1; i <= pr->power.count; i++)
-                       if (pr->power.states[i].valid)
-                               printk(" C%d[C%d]", i,
-                                      pr->power.states[i].type);
-               printk(")\n");
        }
-
+#ifdef CONFIG_ACPI_PROCFS
        /* 'power' [R] */
        entry = proc_create_data(ACPI_PROCESSOR_FILE_POWER,
                                 S_IRUGO, acpi_device_dir(device),
@@ -1194,6 +1228,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
                                 acpi_driver_data(device));
        if (!entry)
                return -EIO;
+#endif
        return 0;
 }
 
@@ -1206,9 +1241,11 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
        cpuidle_unregister_device(&pr->power.dev);
        pr->flags.power_setup_done = 0;
 
+#ifdef CONFIG_ACPI_PROCFS
        if (acpi_device_dir(device))
                remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
                                  acpi_device_dir(device));
+#endif
 
        return 0;
 }