@@ -849,73 +851,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
return idle_time;
}
-/**
- * acpi_idle_enter_simple - enters an ACPI state without BM handling
- * @dev: the target CPU
- * @state: the state data
- */
-static int acpi_idle_enter_simple(struct cpuidle_device *dev,
- struct cpuidle_state *state)
-{
- struct acpi_processor *pr;
- struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- ktime_t kt1, kt2;
- s64 idle_time;
- s64 sleep_ticks = 0;
-
- pr = __get_cpu_var(processors);
-
- if (unlikely(!pr))
- return 0;
-
- if (acpi_idle_suspend)
- 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 (unlikely(need_resched())) {
- current_thread_info()->status |= TS_POLLING;
- local_irq_enable();
- return 0;
- }
-
- /*
- * Must be done before busmaster disable as we might need to
- * access HPET !
- */
- lapic_timer_state_broadcast(pr, cx, 1);
-
- if (cx->type == ACPI_STATE_C3)
- ACPI_FLUSH_CPU_CACHE();
-
- kt1 = ktime_get_real();
- /* Tell the scheduler that we are going deep-idle: */
- sched_clock_idle_sleep_event();
- acpi_idle_do_entry(cx);
- kt2 = ktime_get_real();
- idle_time = ktime_to_us(ktime_sub(kt2, kt1));
-
- sleep_ticks = us_to_pm_timer_ticks(idle_time);
-
- /* Tell the scheduler how much we idled: */
- sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
-
- local_irq_enable();
- current_thread_info()->status |= TS_POLLING;
-
- cx->usage++;
-
- lapic_timer_state_broadcast(pr, cx, 0);
- cx->time += sleep_ticks;
- return idle_time;
-}
-
static int c3_cpu_count;
static DEFINE_SPINLOCK(c3_lock);
@@ -944,7 +879,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
if (acpi_idle_suspend)
return(acpi_idle_enter_c1(dev, state));
- if (acpi_idle_bm_check()) {
+ if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check && acpi_idle_bm_check()) {
if (dev->safe_state) {
dev->last_state = dev->safe_state;
return dev->safe_state->enter(dev, dev->safe_state);
@@ -970,17 +905,24 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
return 0;
}
- acpi_unlazy_tlb(smp_processor_id());
+ if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check)
+ acpi_unlazy_tlb(smp_processor_id());
/* Tell the scheduler that we are going deep-idle: */
- sched_clock_idle_sleep_event();
+ if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check)
+ sched_clock_idle_sleep_event();
/*
* Must be done before busmaster disable as we might need to
* access HPET !
*/
lapic_timer_state_broadcast(pr, cx, 1);
+ if (cx->type == ACPI_STATE_C3 && !pr->flags.bm_check)
+ ACPI_FLUSH_CPU_CACHE();
+
kt1 = ktime_get_real();
+ if (cx->type != ACPI_STATE_C3 || !pr->flags.bm_check)
+ sched_clock_idle_sleep_event();
/*
* disable bus master
* bm_check implies we need ARB_DIS
@@ -991,21 +933,19 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
* 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 (cx->type == ACPI_STATE_C3 && pr->flags.bm_check && pr->flags.bm_control) {
spin_lock(&c3_lock);
c3_cpu_count++;
/* Disable bus master arbitration when all CPUs are in C3 */
if (c3_cpu_count == num_online_cpus())
acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
spin_unlock(&c3_lock);
- } else if (!pr->flags.bm_check) {
- ACPI_FLUSH_CPU_CACHE();
}
acpi_idle_do_entry(cx);
/* Re-enable bus master arbitration */
- if (pr->flags.bm_check && pr->flags.bm_control) {
+ if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check && pr->flags.bm_control) {
spin_lock(&c3_lock);
acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
c3_cpu_count--;
@@ -1095,7 +1035,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
case ACPI_STATE_C2:
state->flags |= CPUIDLE_FLAG_BALANCED;
state->flags |= CPUIDLE_FLAG_TIME_VALID;
- state->enter = acpi_idle_enter_simple;
+ state->enter = acpi_idle_enter_bm;
dev->safe_state = state;
break;
@@ -1103,9 +1043,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
state->flags |= CPUIDLE_FLAG_DEEP;
state->flags |= CPUIDLE_FLAG_TIME_VALID;
state->flags |= CPUIDLE_FLAG_CHECK_BM;
- state->enter = pr->flags.bm_check ?
- acpi_idle_enter_bm :
- acpi_idle_enter_simple;
+ state->enter = acpi_idle_enter_bm;
break;
}