aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_idle.c
diff options
context:
space:
mode:
authorVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>2007-11-19 21:43:22 -0500
committerLen Brown <len.brown@intel.com>2007-11-19 21:43:22 -0500
commitddc081a19585c8ba5aad437779950c2ef215360a (patch)
treebea2be9bb259a336cb3be7f0babfb5bd571517da /drivers/acpi/processor_idle.c
parent5062911830a66df0c0ad28c387a8c0623cb0d28c (diff)
cpuidle: fix HP nx6125 regression
Fix for http://bugzilla.kernel.org/show_bug.cgi?id=9355 cpuidle always used to fallback to C2 if there is some bm activity while entering C3. But, presence of C2 is not always guaranteed. Change cpuidle algorithm to detect a safe_state to fallback in case of bm_activity and use that state instead of C2. 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.c125
1 files changed, 55 insertions, 70 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 1af0694e8520..8904f5c82a1c 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -197,6 +197,19 @@ static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
197 return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); 197 return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
198} 198}
199 199
200static void acpi_safe_halt(void)
201{
202 current_thread_info()->status &= ~TS_POLLING;
203 /*
204 * TS_POLLING-cleared state must be visible before we
205 * test NEED_RESCHED:
206 */
207 smp_mb();
208 if (!need_resched())
209 safe_halt();
210 current_thread_info()->status |= TS_POLLING;
211}
212
200#ifndef CONFIG_CPU_IDLE 213#ifndef CONFIG_CPU_IDLE
201 214
202static void 215static void
@@ -239,19 +252,6 @@ acpi_processor_power_activate(struct acpi_processor *pr,
239 return; 252 return;
240} 253}
241 254
242static void acpi_safe_halt(void)
243{
244 current_thread_info()->status &= ~TS_POLLING;
245 /*
246 * TS_POLLING-cleared state must be visible before we
247 * test NEED_RESCHED:
248 */
249 smp_mb();
250 if (!need_resched())
251 safe_halt();
252 current_thread_info()->status |= TS_POLLING;
253}
254
255static atomic_t c3_cpu_count; 255static atomic_t c3_cpu_count;
256 256
257/* Common C-state entry for C2, C3, .. */ 257/* Common C-state entry for C2, C3, .. */
@@ -1385,15 +1385,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
1385 if (pr->flags.bm_check) 1385 if (pr->flags.bm_check)
1386 acpi_idle_update_bm_rld(pr, cx); 1386 acpi_idle_update_bm_rld(pr, cx);
1387 1387
1388 current_thread_info()->status &= ~TS_POLLING; 1388 acpi_safe_halt();
1389 /*
1390 * TS_POLLING-cleared state must be visible before we test
1391 * NEED_RESCHED:
1392 */
1393 smp_mb();
1394 if (!need_resched())
1395 safe_halt();
1396 current_thread_info()->status |= TS_POLLING;
1397 1389
1398 cx->usage++; 1390 cx->usage++;
1399 1391
@@ -1493,6 +1485,15 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1493 if (acpi_idle_suspend) 1485 if (acpi_idle_suspend)
1494 return(acpi_idle_enter_c1(dev, state)); 1486 return(acpi_idle_enter_c1(dev, state));
1495 1487
1488 if (acpi_idle_bm_check()) {
1489 if (dev->safe_state) {
1490 return dev->safe_state->enter(dev, dev->safe_state);
1491 } else {
1492 acpi_safe_halt();
1493 return 0;
1494 }
1495 }
1496
1496 local_irq_disable(); 1497 local_irq_disable();
1497 current_thread_info()->status &= ~TS_POLLING; 1498 current_thread_info()->status &= ~TS_POLLING;
1498 /* 1499 /*
@@ -1515,49 +1516,39 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1515 */ 1516 */
1516 acpi_state_timer_broadcast(pr, cx, 1); 1517 acpi_state_timer_broadcast(pr, cx, 1);
1517 1518
1518 if (acpi_idle_bm_check()) { 1519 acpi_idle_update_bm_rld(pr, cx);
1519 cx = pr->power.bm_state;
1520
1521 acpi_idle_update_bm_rld(pr, cx);
1522
1523 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1524 acpi_idle_do_entry(cx);
1525 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1526 } else {
1527 acpi_idle_update_bm_rld(pr, cx);
1528 1520
1529 /* 1521 /*
1530 * disable bus master 1522 * disable bus master
1531 * bm_check implies we need ARB_DIS 1523 * bm_check implies we need ARB_DIS
1532 * !bm_check implies we need cache flush 1524 * !bm_check implies we need cache flush
1533 * bm_control implies whether we can do ARB_DIS 1525 * bm_control implies whether we can do ARB_DIS
1534 * 1526 *
1535 * That leaves a case where bm_check is set and bm_control is 1527 * That leaves a case where bm_check is set and bm_control is
1536 * not set. In that case we cannot do much, we enter C3 1528 * not set. In that case we cannot do much, we enter C3
1537 * without doing anything. 1529 * without doing anything.
1538 */ 1530 */
1539 if (pr->flags.bm_check && pr->flags.bm_control) { 1531 if (pr->flags.bm_check && pr->flags.bm_control) {
1540 spin_lock(&c3_lock); 1532 spin_lock(&c3_lock);
1541 c3_cpu_count++; 1533 c3_cpu_count++;
1542 /* Disable bus master arbitration when all CPUs are in C3 */ 1534 /* Disable bus master arbitration when all CPUs are in C3 */
1543 if (c3_cpu_count == num_online_cpus()) 1535 if (c3_cpu_count == num_online_cpus())
1544 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); 1536 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
1545 spin_unlock(&c3_lock); 1537 spin_unlock(&c3_lock);
1546 } else if (!pr->flags.bm_check) { 1538 } else if (!pr->flags.bm_check) {
1547 ACPI_FLUSH_CPU_CACHE(); 1539 ACPI_FLUSH_CPU_CACHE();
1548 } 1540 }
1549 1541
1550 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 1542 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1551 acpi_idle_do_entry(cx); 1543 acpi_idle_do_entry(cx);
1552 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 1544 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1553 1545
1554 /* Re-enable bus master arbitration */ 1546 /* Re-enable bus master arbitration */
1555 if (pr->flags.bm_check && pr->flags.bm_control) { 1547 if (pr->flags.bm_check && pr->flags.bm_control) {
1556 spin_lock(&c3_lock); 1548 spin_lock(&c3_lock);
1557 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); 1549 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
1558 c3_cpu_count--; 1550 c3_cpu_count--;
1559 spin_unlock(&c3_lock); 1551 spin_unlock(&c3_lock);
1560 }
1561 } 1552 }
1562 1553
1563#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 1554#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
@@ -1626,12 +1617,14 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1626 case ACPI_STATE_C1: 1617 case ACPI_STATE_C1:
1627 state->flags |= CPUIDLE_FLAG_SHALLOW; 1618 state->flags |= CPUIDLE_FLAG_SHALLOW;
1628 state->enter = acpi_idle_enter_c1; 1619 state->enter = acpi_idle_enter_c1;
1620 dev->safe_state = state;
1629 break; 1621 break;
1630 1622
1631 case ACPI_STATE_C2: 1623 case ACPI_STATE_C2:
1632 state->flags |= CPUIDLE_FLAG_BALANCED; 1624 state->flags |= CPUIDLE_FLAG_BALANCED;
1633 state->flags |= CPUIDLE_FLAG_TIME_VALID; 1625 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1634 state->enter = acpi_idle_enter_simple; 1626 state->enter = acpi_idle_enter_simple;
1627 dev->safe_state = state;
1635 break; 1628 break;
1636 1629
1637 case ACPI_STATE_C3: 1630 case ACPI_STATE_C3:
@@ -1652,14 +1645,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1652 if (!count) 1645 if (!count)
1653 return -EINVAL; 1646 return -EINVAL;
1654 1647
1655 /* find the deepest state that can handle active BM */
1656 if (pr->flags.bm_check) {
1657 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++)
1658 if (pr->power.states[i].type == ACPI_STATE_C3)
1659 break;
1660 pr->power.bm_state = &pr->power.states[i-1];
1661 }
1662
1663 return 0; 1648 return 0;
1664} 1649}
1665 1650