diff options
author | Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | 2007-11-19 19:48:00 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-11-19 21:25:23 -0500 |
commit | c9c860e5349ef62cd9226694b3aa625ef66f504e (patch) | |
tree | 19ce87dd625256a6a3c73b6eac147b3818d93b18 /drivers/acpi/processor_idle.c | |
parent | 83788c0caed3a425f64fa88fde7c78746b9cdd76 (diff) |
cpuidle: fix C3 for no bus-master control case
Port 18eab8550397f1f3d4b8b2c5257c88dae25d58ed
(Enable C3 even when PM2_control is zero) to cpuidle.
Without this patch, some systems will notice a regression
when enabling CPU_IDLE -- C3 would no longer be available.
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r-- | drivers/acpi/processor_idle.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 0cad56ca342b..943a88069001 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -1514,23 +1514,38 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1514 | } else { | 1514 | } else { |
1515 | acpi_idle_update_bm_rld(pr, cx); | 1515 | acpi_idle_update_bm_rld(pr, cx); |
1516 | 1516 | ||
1517 | spin_lock(&c3_lock); | 1517 | /* |
1518 | c3_cpu_count++; | 1518 | * disable bus master |
1519 | /* Disable bus master arbitration when all CPUs are in C3 */ | 1519 | * bm_check implies we need ARB_DIS |
1520 | if (c3_cpu_count == num_online_cpus()) | 1520 | * !bm_check implies we need cache flush |
1521 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); | 1521 | * bm_control implies whether we can do ARB_DIS |
1522 | spin_unlock(&c3_lock); | 1522 | * |
1523 | * That leaves a case where bm_check is set and bm_control is | ||
1524 | * not set. In that case we cannot do much, we enter C3 | ||
1525 | * without doing anything. | ||
1526 | */ | ||
1527 | if (pr->flags.bm_check && pr->flags.bm_control) { | ||
1528 | spin_lock(&c3_lock); | ||
1529 | c3_cpu_count++; | ||
1530 | /* Disable bus master arbitration when all CPUs are in C3 */ | ||
1531 | if (c3_cpu_count == num_online_cpus()) | ||
1532 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); | ||
1533 | spin_unlock(&c3_lock); | ||
1534 | } else if (!pr->flags.bm_check) { | ||
1535 | ACPI_FLUSH_CPU_CACHE(); | ||
1536 | } | ||
1523 | 1537 | ||
1524 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1538 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
1525 | acpi_idle_do_entry(cx); | 1539 | acpi_idle_do_entry(cx); |
1526 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1540 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
1527 | 1541 | ||
1528 | spin_lock(&c3_lock); | ||
1529 | /* Re-enable bus master arbitration */ | 1542 | /* Re-enable bus master arbitration */ |
1530 | if (c3_cpu_count == num_online_cpus()) | 1543 | if (pr->flags.bm_check && pr->flags.bm_control) { |
1544 | spin_lock(&c3_lock); | ||
1531 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); | 1545 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); |
1532 | c3_cpu_count--; | 1546 | c3_cpu_count--; |
1533 | spin_unlock(&c3_lock); | 1547 | spin_unlock(&c3_lock); |
1548 | } | ||
1534 | } | 1549 | } |
1535 | 1550 | ||
1536 | #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) | 1551 | #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) |