patch-2.4.2 linux/drivers/acpi/cpu.c
Next file: linux/drivers/acpi/dispatcher/dsobject.c
Previous file: linux/drivers/acpi/common/cmxface.c
Back to the patch index
Back to the overall index
- Lines: 227
- Date:
Fri Feb 9 11:45:58 2001
- Orig file:
v2.4.1/linux/drivers/acpi/cpu.c
- Orig date:
Sat Feb 3 19:51:25 2001
diff -u --recursive --new-file v2.4.1/linux/drivers/acpi/cpu.c linux/drivers/acpi/cpu.c
@@ -2,6 +2,7 @@
* cpu.c - Processor handling
*
* Copyright (C) 2000 Andrew Henroid
+ * Copyright (C) 2001 Andrew Grover
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,27 +29,37 @@
#define _COMPONENT OS_DEPENDENT
MODULE_NAME ("cpu")
-unsigned long acpi_c2_exit_latency = ACPI_INFINITE;
-unsigned long acpi_c3_exit_latency = ACPI_INFINITE;
-unsigned long acpi_c2_enter_latency = ACPI_INFINITE;
-unsigned long acpi_c3_enter_latency = ACPI_INFINITE;
+u32 acpi_c2_exit_latency = ACPI_INFINITE;
+u32 acpi_c3_exit_latency = ACPI_INFINITE;
+u32 acpi_c2_enter_latency = ACPI_INFINITE;
+u32 acpi_c3_enter_latency = ACPI_INFINITE;
+u32 acpi_use_idle = TRUE;
+
+u32 acpi_c1_count = 0;
+u32 acpi_c2_count = 0;
+u32 acpi_c3_count = 0;
-static unsigned long acpi_pblk = ACPI_INVALID;
+static u32 acpi_pblk = ACPI_INVALID;
static int acpi_c2_tested = 0;
static int acpi_c3_tested = 0;
static int acpi_max_c_state = 1;
-static int acpi_pm_tmr_len;
+static int acpi_pm_tmr_len = 24;
+#define CPU_POWER_STATES 3
#define MAX_C2_LATENCY 100
#define MAX_C3_LATENCY 1000
+#define ACPI_STATE_C1 0
+#define ACPI_STATE_C2 1
+#define ACPI_STATE_C3 2
+
/*
* Clear busmaster activity flag
*/
static inline void
acpi_clear_bm_activity(void)
{
- acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 0);
+ acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 1);
}
/*
@@ -100,6 +111,7 @@
}
}
+
/*
* Idle loop (uniprocessor only)
*/
@@ -109,14 +121,9 @@
static int sleep_level = 1;
FADT_DESCRIPTOR *fadt = &acpi_fadt;
- if (!fadt
- || (STRNCMP(fadt->header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0)
- || !fadt->Xpm_tmr_blk.address
- || !acpi_pblk)
- goto not_initialized;
-
/*
- * start from the previous sleep level..
+ * start from the previous sleep level.
+ * if not initialized, we goto sleep1
*/
if (sleep_level == 1
|| acpi_max_c_state < 2)
@@ -126,7 +133,7 @@
|| acpi_max_c_state < 3)
goto sleep2;
- sleep3:
+sleep3:
sleep_level = 3;
if (!acpi_c3_tested) {
DEBUG_PRINT(ACPI_INFO, ("C3 works\n"));
@@ -147,6 +154,7 @@
goto sleep2;
time = acpi_read_pm_timer();
+ acpi_c3_count++;
inb(acpi_pblk + ACPI_P_LVL3);
/* Dummy read, force synchronization with the PMU */
acpi_read_pm_timer();
@@ -154,10 +162,10 @@
__sti();
if (diff < acpi_c3_exit_latency)
- goto sleep2;
+ goto sleep1;
}
- sleep3_with_arbiter:
+sleep3_with_arbiter:
for (;;) {
unsigned long time;
unsigned long diff;
@@ -172,6 +180,7 @@
/* Disable arbiter, park on CPU */
acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 1);
+ acpi_c3_count++;
inb(acpi_pblk + ACPI_P_LVL3);
/* Dummy read, force synchronization with the PMU */
acpi_read_pm_timer();
@@ -181,10 +190,10 @@
__sti();
if (diff < acpi_c3_exit_latency)
- goto sleep2;
+ goto sleep1;
}
- sleep2:
+sleep2:
sleep_level = 2;
if (!acpi_c2_tested) {
DEBUG_PRINT(ACPI_INFO, ("C2 works\n"));
@@ -200,6 +209,7 @@
goto out;
time = acpi_read_pm_timer();
+ acpi_c2_count++;
inb(acpi_pblk + ACPI_P_LVL2);
/* Dummy read, force synchronization with the PMU */
acpi_read_pm_timer();
@@ -217,7 +227,7 @@
goto sleep3;
}
- sleep1:
+sleep1:
sleep_level = 1;
acpi_sleep_on_busmaster();
for (;;) {
@@ -228,6 +238,7 @@
if (current->need_resched)
goto out;
time = acpi_read_pm_timer();
+ acpi_c1_count++;
safe_halt();
diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
if (diff > acpi_c2_enter_latency
@@ -235,15 +246,7 @@
goto sleep2;
}
- not_initialized:
- for (;;) {
- __cli();
- if (current->need_resched)
- goto out;
- safe_halt();
- }
-
- out:
+out:
__sti();
}
@@ -278,17 +281,17 @@
acpi_c2_exit_latency
= ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat);
acpi_c2_enter_latency
- = ACPI_MICROSEC_TO_TMR_TICKS(ACPI_TMR_HZ / 1000);
+ = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat * 4);
acpi_max_c_state = 2;
printk(KERN_INFO "ACPI: System firmware supports: C2");
-
+
if (acpi_fadt.plvl3_lat
&& acpi_fadt.plvl3_lat <= MAX_C3_LATENCY) {
acpi_c3_exit_latency
= ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat);
acpi_c3_enter_latency
- = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat * 5);
+ = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat * 12);
acpi_max_c_state = 3;
printk(" C3");
@@ -297,6 +300,10 @@
printk("\n");
}
+ printk(KERN_INFO "ACPI: plvl2lat=%d plvl3lat=%d\n", acpi_fadt.plvl2_lat, acpi_fadt.plvl3_lat);
+ printk(KERN_INFO "ACPI: C2 enter=%d C2 exit=%d\n", acpi_c2_enter_latency, acpi_c2_exit_latency);
+ printk(KERN_INFO "ACPI: C3 enter=%d C3 exit=%d\n", acpi_c3_enter_latency, acpi_c3_exit_latency);
+
return AE_OK;
}
@@ -328,13 +335,19 @@
acpi_pm_timer_init();
-
+ if (acpi_use_idle) {
#ifdef CONFIG_SMP
- if (smp_num_cpus == 1)
- pm_idle = acpi_idle;
+ if (smp_num_cpus == 1)
+ pm_idle = acpi_idle;
#else
- pm_idle = acpi_idle;
+ pm_idle = acpi_idle;
#endif
+ printk(KERN_INFO "ACPI: Using ACPI idle\n");
+ printk(KERN_INFO "ACPI: If experiencing system slowness, try adding \"acpi=no-idle\" to cmdline\n");
+ }
+ else {
+ printk(KERN_INFO "ACPI: Not using ACPI idle\n");
+ }
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)