Bug #271 ยป acpi_cpu.c.diff
acpi_cpu.c 1 Aug 2006 13:19:59 -0000 | ||
---|---|---|
#define ACPI_CPU_NOTIFY_PERF_STATES 0x80 /* _PSS changed. */
|
||
#define ACPI_CPU_NOTIFY_CX_STATES 0x81 /* _CST changed. */
|
||
#define CPU_QUIRK_NO_C3 0x0001 /* C3-type states are not usable. */
|
||
#define CPU_QUIRK_NO_THROTTLE 0x0002 /* Throttling is not usable. */
|
||
#define CPU_QUIRK_NO_C3 (1<<0) /* C3-type states are not usable. */
|
||
#define CPU_QUIRK_NO_THROTTLE (1<<1) /* Throttling is not usable. */
|
||
#define CPU_QUIRK_NO_BM_CTRL (1<<2) /* No bus mastering control. */
|
||
#define PCI_VENDOR_INTEL 0x8086
|
||
#define PCI_DEVICE_82371AB_3 0x7113 /* PIIX4 chipset for quirks. */
|
||
... | ... | |
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||
/* Bus mastering arbitration control is needed for C3. */
|
||
/*
|
||
* Bus mastering arbitration control is needed to keep caches coherent
|
||
* while sleeping in C3. If it's not present but a working flush cache
|
||
* instruction is present, flush the caches before entering C3 instead.
|
||
* Otherwise, just disable C3 completely.
|
||
*/
|
||
if (AcpiGbl_FADT->V1_Pm2CntBlk == 0 || AcpiGbl_FADT->Pm2CntLen == 0) {
|
||
cpu_quirks |= CPU_QUIRK_NO_C3;
|
||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||
"acpi_cpu%d: No BM control, C3 disabled\n",
|
||
device_get_unit(sc->cpu_dev)));
|
||
if (AcpiGbl_FADT->WbInvd && AcpiGbl_FADT->WbInvdFlush == 0) {
|
||
cpu_quirks |= CPU_QUIRK_NO_BM_CTRL;
|
||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||
"acpi_cpu%d: no BM control, using flush cache method\n",
|
||
device_get_unit(sc->cpu_dev)));
|
||
} else {
|
||
cpu_quirks |= CPU_QUIRK_NO_C3;
|
||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||
"acpi_cpu%d: no BM control, C3 not available\n",
|
||
device_get_unit(sc->cpu_dev)));
|
||
}
|
||
}
|
||
/*
|
||
... | ... | |
* driver polling for new devices keeps this bit set all the
|
||
* time if USB is loaded.
|
||
*/
|
||
AcpiGetRegister(ACPI_BITREG_BUS_MASTER_STATUS, &bm_active,
|
||
ACPI_MTX_DO_NOT_LOCK);
|
||
if (bm_active != 0) {
|
||
AcpiSetRegister(ACPI_BITREG_BUS_MASTER_STATUS, 1,
|
||
ACPI_MTX_DO_NOT_LOCK);
|
||
cx_next_idx = min(cx_next_idx, cpu_non_c3);
|
||
if ((cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) {
|
||
AcpiGetRegister(ACPI_BITREG_BUS_MASTER_STATUS, &bm_active,
|
||
ACPI_MTX_DO_NOT_LOCK);
|
||
if (bm_active != 0) {
|
||
AcpiSetRegister(ACPI_BITREG_BUS_MASTER_STATUS, 1,
|
||
ACPI_MTX_DO_NOT_LOCK);
|
||
cx_next_idx = min(cx_next_idx, cpu_non_c3);
|
||
}
|
||
}
|
||
/* Select the next state and update statistics. */
|
||
... | ... | |
return;
|
||
}
|
||
/* For C3, disable bus master arbitration and enable bus master wake. */
|
||
/*
|
||
* For C3, disable bus master arbitration and enable bus master wake
|
||
* if BM control is available, otherwise flush the CPU cache.
|
||
*/
|
||
if (cx_next->type == ACPI_STATE_C3) {
|
||
AcpiSetRegister(ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
|
||
AcpiSetRegister(ACPI_BITREG_BUS_MASTER_RLD, 1, ACPI_MTX_DO_NOT_LOCK);
|
||
if ((cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) {
|
||
AcpiSetRegister(ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
|
||
AcpiSetRegister(ACPI_BITREG_BUS_MASTER_RLD, 1,
|
||
ACPI_MTX_DO_NOT_LOCK);
|
||
} else
|
||
ACPI_FLUSH_CPU_CACHE();
|
||
}
|
||
/*
|
||
... | ... | |
AcpiHwLowLevelRead(32, &end_time, &AcpiGbl_FADT->XPmTmrBlk);
|
||
/* Enable bus master arbitration and disable bus master wakeup. */
|
||
if (cx_next->type == ACPI_STATE_C3) {
|
||
if (cx_next->type == ACPI_STATE_C3 &&
|
||
(cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) {
|
||
AcpiSetRegister(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK);
|
||
AcpiSetRegister(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK);
|
||
}
|
||
... | ... | |
{
|
||
/*
|
||
* C3 is not supported on multiple CPUs since this would require
|
||
* flushing all caches which is currently too expensive.
|
||
* C3 on multiple CPUs requires using the expensive flush cache
|
||
* instruction.
|
||
*/
|
||
if (ncpus > 1)
|
||
cpu_quirks |= CPU_QUIRK_NO_C3;
|
||
cpu_quirks |= CPU_QUIRK_NO_BM_CTRL;
|
||
#ifdef notyet
|
||
/* Look for various quirks of the PIIX4 part. */
|