ACPI: Enable C3 even when PM2_control is zero
On systems that do not have pm2_control_block, we cannot really use ARB_DISABLE before C3. We used to disable C3 totally on such systems. To be compatible with Windows, we need to enable C3 on such systems now. We just skip ARB_DISABLE step before entering the C3-state and assume hardware is handling things correctly. Also, ACPI spec is not clear about pm2_control is _needed_ for C3 or not. We have atleast one system that need this to enable C3. Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
committed by
Len Brown
parent
33ce203343
commit
18eab85503
@@ -488,7 +488,17 @@ static void acpi_processor_idle(void)
|
|||||||
|
|
||||||
case ACPI_STATE_C3:
|
case ACPI_STATE_C3:
|
||||||
|
|
||||||
if (pr->flags.bm_check) {
|
/*
|
||||||
|
* disable bus master
|
||||||
|
* bm_check implies we need ARB_DIS
|
||||||
|
* !bm_check implies we need cache flush
|
||||||
|
* bm_control implies whether we can do ARB_DIS
|
||||||
|
*
|
||||||
|
* That leaves a case where bm_check is set and bm_control is
|
||||||
|
* 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 (atomic_inc_return(&c3_cpu_count) ==
|
if (atomic_inc_return(&c3_cpu_count) ==
|
||||||
num_online_cpus()) {
|
num_online_cpus()) {
|
||||||
/*
|
/*
|
||||||
@@ -497,7 +507,7 @@ static void acpi_processor_idle(void)
|
|||||||
*/
|
*/
|
||||||
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
|
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!pr->flags.bm_check) {
|
||||||
/* SMP with no shared cache... Invalidate cache */
|
/* SMP with no shared cache... Invalidate cache */
|
||||||
ACPI_FLUSH_CPU_CACHE();
|
ACPI_FLUSH_CPU_CACHE();
|
||||||
}
|
}
|
||||||
@@ -509,7 +519,7 @@ static void acpi_processor_idle(void)
|
|||||||
acpi_cstate_enter(cx);
|
acpi_cstate_enter(cx);
|
||||||
/* Get end time (ticks) */
|
/* Get end time (ticks) */
|
||||||
t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
|
t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
|
||||||
if (pr->flags.bm_check) {
|
if (pr->flags.bm_check && pr->flags.bm_control) {
|
||||||
/* Enable bus master arbitration */
|
/* Enable bus master arbitration */
|
||||||
atomic_dec(&c3_cpu_count);
|
atomic_dec(&c3_cpu_count);
|
||||||
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
|
acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
|
||||||
@@ -959,9 +969,9 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
|
|||||||
if (pr->flags.bm_check) {
|
if (pr->flags.bm_check) {
|
||||||
/* bus mastering control is necessary */
|
/* bus mastering control is necessary */
|
||||||
if (!pr->flags.bm_control) {
|
if (!pr->flags.bm_control) {
|
||||||
|
/* In this case we enter C3 without bus mastering */
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||||
"C3 support requires bus mastering control\n"));
|
"C3 support without bus mastering control\n"));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user