Project

General

Profile

Bug #271 ยป acpi_cpu.c.diff

qhwt+dfly, 08/01/2006 01:39 PM

View differences:

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. */
    (1-1/1)