]> err.no Git - linux-2.6/blobdiff - drivers/acpi/processor_idle.c
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzi...
[linux-2.6] / drivers / acpi / processor_idle.c
index 8904f5c82a1c09781c10889178356fd85d26fc54..2235f4e02d26f46267b512a0d3c4c14badc34526 100644 (file)
@@ -76,7 +76,11 @@ static void (*pm_idle_save) (void) __read_mostly;
 #define PM_TIMER_TICKS_TO_US(p)                (((p) * 1000)/(PM_TIMER_FREQUENCY/1000))
 
 static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
+#ifdef CONFIG_CPU_IDLE
 module_param(max_cstate, uint, 0000);
+#else
+module_param(max_cstate, uint, 0644);
+#endif
 static unsigned int nocst __read_mostly;
 module_param(nocst, uint, 0000);
 
@@ -102,7 +106,7 @@ static int acpi_processor_set_power_policy(struct acpi_processor *pr);
  *
  * To skip this limit, boot/load with a large max_cstate limit.
  */
-static int set_max_cstate(struct dmi_system_id *id)
+static int set_max_cstate(const struct dmi_system_id *id)
 {
        if (max_cstate > ACPI_PROCESSOR_MAX_POWER)
                return 0;
@@ -299,21 +303,12 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,
 
 static void acpi_propagate_timer_broadcast(struct acpi_processor *pr)
 {
-#ifdef CONFIG_GENERIC_CLOCKEVENTS
        unsigned long reason;
 
        reason = pr->power.timer_broadcast_on_state < INT_MAX ?
                CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
 
        clockevents_notify(reason, &pr->id);
-#else
-       cpumask_t mask = cpumask_of_cpu(pr->id);
-
-       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
 }
 
 /* Power(C) State timer broadcast control */
@@ -321,8 +316,6 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr,
                                       struct acpi_processor_cx *cx,
                                       int broadcast)
 {
-#ifdef CONFIG_GENERIC_CLOCKEVENTS
-
        int state = cx - pr->power.states;
 
        if (state >= pr->power.timer_broadcast_on_state) {
@@ -332,7 +325,6 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr,
                        CLOCK_EVT_NOTIFY_BROADCAST_EXIT;
                clockevents_notify(reason, &pr->id);
        }
-#endif
 }
 
 #else
@@ -542,6 +534,11 @@ static void acpi_processor_idle(void)
                break;
 
        case ACPI_STATE_C3:
+               /*
+                * Must be done before busmaster disable as we might
+                * need to access HPET !
+                */
+               acpi_state_timer_broadcast(pr, cx, 1);
                /*
                 * disable bus master
                 * bm_check implies we need ARB_DIS
@@ -569,7 +566,6 @@ static void acpi_processor_idle(void)
                /* Get start time (ticks) */
                t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
                /* Invoke C3 */
-               acpi_state_timer_broadcast(pr, cx, 1);
                /* Tell the scheduler that we are going deep-idle: */
                sched_clock_idle_sleep_event();
                acpi_cstate_enter(cx);
@@ -1413,9 +1409,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
        if (acpi_idle_suspend)
                return(acpi_idle_enter_c1(dev, state));
 
-       if (pr->flags.bm_check)
-               acpi_idle_update_bm_rld(pr, cx);
-
        local_irq_disable();
        current_thread_info()->status &= ~TS_POLLING;
        /*
@@ -1430,13 +1423,21 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
                return 0;
        }
 
+       /*
+        * Must be done before busmaster disable as we might need to
+        * access HPET !
+        */
+       acpi_state_timer_broadcast(pr, cx, 1);
+
+       if (pr->flags.bm_check)
+               acpi_idle_update_bm_rld(pr, cx);
+
        if (cx->type == ACPI_STATE_C3)
                ACPI_FLUSH_CPU_CACHE();
 
        t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
        /* Tell the scheduler that we are going deep-idle: */
        sched_clock_idle_sleep_event();
-       acpi_state_timer_broadcast(pr, cx, 1);
        acpi_idle_do_entry(cx);
        t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 
@@ -1685,6 +1686,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
 
        if (!first_run) {
                dmi_check_system(processor_power_dmi_table);
+               max_cstate = acpi_processor_cstate_check(max_cstate);
                if (max_cstate < ACPI_C_STATES_MAX)
                        printk(KERN_NOTICE
                               "ACPI: processor limited to max C-state %d\n",