diff options
author | Len Brown <len.brown@intel.com> | 2009-01-28 18:28:09 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-01-28 19:15:54 -0500 |
commit | 31878dd86b7df9a147f5e6cc6e07092b4308782b (patch) | |
tree | e99eaf24e4d813bf43737f02c8746c17383a841d /drivers | |
parent | a2b7b01c072435b7832ab392167545a1b38cabc3 (diff) |
ACPI: remove BM_RLD access from idle entry path
It is true that BM_RLD needs to be set to enable
bus master activity to wake an older chipset (eg PIIX4) from C3.
This is contrary to the erroneous wording the ACPI 2.0, 3.0
specifications that suggests that BM_RLD is an indicator
rather than a control bit.
ACPI 1.0's correct wording should be restored in ACPI 4.0:
http://www.acpica.org/bugzilla/show_bug.cgi?id=689
But the kernel should not have to clear BM_RLD
when entering a non C3-type state just to set
it again when entering a C3-type C-state.
We should be able to set BM_RLD at boot time
and leave it alone -- removing the overhead of
accessing this IO register from the idle entry path.
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/processor_idle.c | 57 |
1 files changed, 9 insertions, 48 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index ae0010821ce3..7eab733ae96e 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -241,26 +241,6 @@ acpi_processor_power_activate(struct acpi_processor *pr, | |||
241 | old->promotion.count = 0; | 241 | old->promotion.count = 0; |
242 | new->demotion.count = 0; | 242 | new->demotion.count = 0; |
243 | 243 | ||
244 | /* Cleanup from old state. */ | ||
245 | if (old) { | ||
246 | switch (old->type) { | ||
247 | case ACPI_STATE_C3: | ||
248 | /* Disable bus master reload */ | ||
249 | if (new->type != ACPI_STATE_C3 && pr->flags.bm_check) | ||
250 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); | ||
251 | break; | ||
252 | } | ||
253 | } | ||
254 | |||
255 | /* Prepare to use new state. */ | ||
256 | switch (new->type) { | ||
257 | case ACPI_STATE_C3: | ||
258 | /* Enable bus master reload */ | ||
259 | if (old->type != ACPI_STATE_C3 && pr->flags.bm_check) | ||
260 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); | ||
261 | break; | ||
262 | } | ||
263 | |||
264 | pr->power.state = new; | 244 | pr->power.state = new; |
265 | 245 | ||
266 | return; | 246 | return; |
@@ -1121,7 +1101,6 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | |||
1121 | " for C3 to be enabled on SMP systems\n")); | 1101 | " for C3 to be enabled on SMP systems\n")); |
1122 | return; | 1102 | return; |
1123 | } | 1103 | } |
1124 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); | ||
1125 | } | 1104 | } |
1126 | 1105 | ||
1127 | /* | 1106 | /* |
@@ -1137,6 +1116,15 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | |||
1137 | #else | 1116 | #else |
1138 | cx->latency_ticks = cx->latency; | 1117 | cx->latency_ticks = cx->latency; |
1139 | #endif | 1118 | #endif |
1119 | /* | ||
1120 | * On older chipsets, BM_RLD needs to be set | ||
1121 | * in order for Bus Master activity to wake the | ||
1122 | * system from C3. Newer chipsets handle DMA | ||
1123 | * during C3 automatically and BM_RLD is a NOP. | ||
1124 | * In either case, the proper way to | ||
1125 | * handle BM_RLD is to set it and leave it set. | ||
1126 | */ | ||
1127 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); | ||
1140 | 1128 | ||
1141 | return; | 1129 | return; |
1142 | } | 1130 | } |
@@ -1400,25 +1388,6 @@ static int acpi_idle_bm_check(void) | |||
1400 | } | 1388 | } |
1401 | 1389 | ||
1402 | /** | 1390 | /** |
1403 | * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state | ||
1404 | * @pr: the processor | ||
1405 | * @target: the new target state | ||
1406 | */ | ||
1407 | static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr, | ||
1408 | struct acpi_processor_cx *target) | ||
1409 | { | ||
1410 | if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) { | ||
1411 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); | ||
1412 | pr->flags.bm_rld_set = 0; | ||
1413 | } | ||
1414 | |||
1415 | if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) { | ||
1416 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); | ||
1417 | pr->flags.bm_rld_set = 1; | ||
1418 | } | ||
1419 | } | ||
1420 | |||
1421 | /** | ||
1422 | * acpi_idle_do_entry - a helper function that does C2 and C3 type entry | 1391 | * acpi_idle_do_entry - a helper function that does C2 and C3 type entry |
1423 | * @cx: cstate data | 1392 | * @cx: cstate data |
1424 | * | 1393 | * |
@@ -1473,9 +1442,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
1473 | return 0; | 1442 | return 0; |
1474 | } | 1443 | } |
1475 | 1444 | ||
1476 | if (pr->flags.bm_check) | ||
1477 | acpi_idle_update_bm_rld(pr, cx); | ||
1478 | |||
1479 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1445 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
1480 | acpi_idle_do_entry(cx); | 1446 | acpi_idle_do_entry(cx); |
1481 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1447 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
@@ -1527,9 +1493,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
1527 | */ | 1493 | */ |
1528 | acpi_state_timer_broadcast(pr, cx, 1); | 1494 | acpi_state_timer_broadcast(pr, cx, 1); |
1529 | 1495 | ||
1530 | if (pr->flags.bm_check) | ||
1531 | acpi_idle_update_bm_rld(pr, cx); | ||
1532 | |||
1533 | if (cx->type == ACPI_STATE_C3) | 1496 | if (cx->type == ACPI_STATE_C3) |
1534 | ACPI_FLUSH_CPU_CACHE(); | 1497 | ACPI_FLUSH_CPU_CACHE(); |
1535 | 1498 | ||
@@ -1621,8 +1584,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1621 | */ | 1584 | */ |
1622 | acpi_state_timer_broadcast(pr, cx, 1); | 1585 | acpi_state_timer_broadcast(pr, cx, 1); |
1623 | 1586 | ||
1624 | acpi_idle_update_bm_rld(pr, cx); | ||
1625 | |||
1626 | /* | 1587 | /* |
1627 | * disable bus master | 1588 | * disable bus master |
1628 | * bm_check implies we need ARB_DIS | 1589 | * bm_check implies we need ARB_DIS |