patch-2.4.0-prerelease linux/drivers/acpi/cpu.c
Next file: linux/drivers/acpi/dispatcher/Makefile
Previous file: linux/drivers/acpi/common/cmxface.c
Back to the patch index
Back to the overall index
- Lines: 341
- Date:
Fri Dec 29 14:07:21 2000
- Orig file:
v2.4.0-test12/linux/drivers/acpi/cpu.c
- Orig date:
Sun Oct 8 10:50:13 2000
diff -u --recursive --new-file v2.4.0-test12/linux/drivers/acpi/cpu.c linux/drivers/acpi/cpu.c
@@ -37,55 +37,65 @@
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;
/*
* Clear busmaster activity flag
*/
static inline void
-acpi_clear_bm_activity(struct acpi_facp *facp)
+acpi_clear_bm_activity(void)
{
- acpi_write_pm1_status(facp, ACPI_BM);
+ acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 0);
}
/*
* Returns 1 if there has been busmaster activity
*/
static inline int
-acpi_bm_activity(struct acpi_facp *facp)
+acpi_bm_activity(void)
{
- return acpi_read_pm1_status(facp) & ACPI_BM;
+ return acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, BM_STS);
}
/*
* Set system to sleep through busmaster requests
*/
static void
-acpi_sleep_on_busmaster(struct acpi_facp *facp)
+acpi_sleep_on_busmaster(void)
{
- u32 pm1_cntr = acpi_read_pm1_control(facp);
- if (pm1_cntr & ACPI_BM_RLD) {
- pm1_cntr &= ~ACPI_BM_RLD;
- acpi_write_pm1_control(facp, pm1_cntr);
- }
+ acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1);
}
/*
* Set system to wake on busmaster requests
*/
static void
-acpi_wake_on_busmaster(struct acpi_facp *facp)
+acpi_wake_on_busmaster(void)
{
- u32 pm1_cntr = acpi_read_pm1_control(facp);
- if (!(pm1_cntr & ACPI_BM_RLD)) {
- pm1_cntr |= ACPI_BM_RLD;
- acpi_write_pm1_control(facp, pm1_cntr);
- }
- acpi_clear_bm_activity(facp);
+ acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0);
}
-/* The ACPI timer is just the low 24 bits */
-#define TIME_BEGIN(tmr) inl(tmr)
-#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff)
+u32
+acpi_read_pm_timer(void)
+{
+ return acpi_hw_register_read(ACPI_MTX_LOCK, PM_TIMER);
+}
+
+/*
+ * Do a compare, accounting for 24/32bit rollover
+ */
+static u32
+acpi_compare_pm_timers(u32 first, u32 second)
+{
+ if (first < second) {
+ return (second - first);
+ } else {
+ if (acpi_pm_tmr_len == 24)
+ return (second + (0xFFFFFF - first));
+ else
+ return (second + (0xFFFFFFFF - first));
+ }
+}
/*
* Idle loop (uniprocessor only)
@@ -94,11 +104,11 @@
acpi_idle(void)
{
static int sleep_level = 1;
- struct acpi_facp *facp = &acpi_facp;
+ FADT_DESCRIPTOR *fadt = &acpi_fadt;
- if (!facp
- || facp->hdr.signature != ACPI_FACP_SIG
- || !facp->pm_tmr
+ if (!fadt
+ || (STRNCMP(fadt->header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0)
+ || !fadt->Xpm_tmr_blk.address
|| !acpi_pblk)
goto not_initialized;
@@ -116,110 +126,108 @@
sleep3:
sleep_level = 3;
if (!acpi_c3_tested) {
- printk(KERN_DEBUG "ACPI C3 works\n");
+ DEBUG_PRINT(ACPI_INFO, ("C3 works\n"));
acpi_c3_tested = 1;
}
- acpi_wake_on_busmaster(facp);
- if (facp->pm2_cnt)
+ acpi_wake_on_busmaster();
+ if (fadt->Xpm2_cnt_blk.address)
goto sleep3_with_arbiter;
for (;;) {
unsigned long time;
- unsigned int pm_tmr = facp->pm_tmr;
-
+ unsigned long diff;
+
__cli();
if (current->need_resched)
goto out;
- if (acpi_bm_activity(facp))
+ if (acpi_bm_activity())
goto sleep2;
- time = TIME_BEGIN(pm_tmr);
+ time = acpi_read_pm_timer();
inb(acpi_pblk + ACPI_P_LVL3);
/* Dummy read, force synchronization with the PMU */
- inl(pm_tmr);
- time = TIME_END(pm_tmr, time);
+ acpi_read_pm_timer();
+ diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
__sti();
- if (time < acpi_c3_exit_latency)
+ if (diff < acpi_c3_exit_latency)
goto sleep2;
}
sleep3_with_arbiter:
for (;;) {
unsigned long time;
- u8 arbiter;
- unsigned int pm2_cntr = facp->pm2_cnt;
- unsigned int pm_tmr = facp->pm_tmr;
+ unsigned long diff;
__cli();
if (current->need_resched)
goto out;
- if (acpi_bm_activity(facp))
+ if (acpi_bm_activity())
goto sleep2;
- time = TIME_BEGIN(pm_tmr);
- arbiter = inb(pm2_cntr) & ~ACPI_ARB_DIS;
+ time = acpi_read_pm_timer();
+
/* Disable arbiter, park on CPU */
- outb(arbiter | ACPI_ARB_DIS, pm2_cntr);
+ acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 1);
inb(acpi_pblk + ACPI_P_LVL3);
/* Dummy read, force synchronization with the PMU */
- inl(pm_tmr);
- time = TIME_END(pm_tmr, time);
+ acpi_read_pm_timer();
+ diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
/* Enable arbiter again.. */
- outb(arbiter, pm2_cntr);
+ acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 0);
__sti();
- if (time < acpi_c3_exit_latency)
+ if (diff < acpi_c3_exit_latency)
goto sleep2;
}
sleep2:
sleep_level = 2;
if (!acpi_c2_tested) {
- printk(KERN_DEBUG "ACPI C2 works\n");
+ DEBUG_PRINT(ACPI_INFO, ("C2 works\n"));
acpi_c2_tested = 1;
}
- acpi_wake_on_busmaster(facp); /* Required to track BM activity.. */
+ acpi_wake_on_busmaster(); /* Required to track BM activity.. */
for (;;) {
unsigned long time;
- unsigned int pm_tmr = facp->pm_tmr;
+ unsigned long diff;
__cli();
if (current->need_resched)
goto out;
- time = TIME_BEGIN(pm_tmr);
+ time = acpi_read_pm_timer();
inb(acpi_pblk + ACPI_P_LVL2);
/* Dummy read, force synchronization with the PMU */
- inl(pm_tmr);
- time = TIME_END(pm_tmr, time);
+ acpi_read_pm_timer();
+ diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
__sti();
- if (time < acpi_c2_exit_latency)
+ if (diff < acpi_c2_exit_latency)
goto sleep1;
- if (acpi_bm_activity(facp)) {
- acpi_clear_bm_activity(facp);
+ if (acpi_bm_activity()) {
+ acpi_clear_bm_activity();
continue;
}
- if (time > acpi_c3_enter_latency
+ if (diff > acpi_c3_enter_latency
&& acpi_max_c_state >= 3)
goto sleep3;
}
sleep1:
sleep_level = 1;
- acpi_sleep_on_busmaster(facp);
+ acpi_sleep_on_busmaster();
for (;;) {
unsigned long time;
- unsigned int pm_tmr = facp->pm_tmr;
+ unsigned long diff;
__cli();
if (current->need_resched)
goto out;
- time = TIME_BEGIN(pm_tmr);
+ time = acpi_read_pm_timer();
safe_halt();
- time = TIME_END(pm_tmr, time);
- if (time > acpi_c2_enter_latency
+ diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
+ if (diff > acpi_c2_enter_latency
&& acpi_max_c_state >= 2)
goto sleep2;
}
@@ -240,7 +248,7 @@
* Get processor information
*/
static ACPI_STATUS
-acpi_find_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
+acpi_found_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
{
ACPI_OBJECT obj;
ACPI_CX_STATE lat[4];
@@ -253,10 +261,11 @@
if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf)))
return AE_OK;
- printk(KERN_INFO "ACPI: PBLK %d @ 0x%04x:%d\n",
- obj.processor.proc_id,
- obj.processor.pblk_address,
- obj.processor.pblk_length);
+ DEBUG_PRINT(ACPI_INFO, ("PBLK %d @ 0x%04x:%d\n",
+ obj.processor.proc_id,
+ obj.processor.pblk_address,
+ obj.processor.pblk_length));
+
if (acpi_pblk != ACPI_INVALID
|| !obj.processor.pblk_address
|| obj.processor.pblk_length != 6)
@@ -270,19 +279,16 @@
return AE_OK;
if (lat[2].latency < MAX_CX_STATE_LATENCY) {
- printk(KERN_INFO "ACPI: C2");
+ printk(KERN_INFO "ACPI: System firmware supports: C2");
acpi_c2_exit_latency = lat[2].latency;
acpi_max_c_state = 2;
if (lat[3].latency < MAX_CX_STATE_LATENCY) {
- printk(", C3 supported\n");
+ printk(" C3");
acpi_c3_exit_latency = lat[3].latency;
acpi_max_c_state = 3;
}
- else {
- printk(" supported\n");
- }
-
+ printk("\n");
}
memset(throttle, 0, sizeof(throttle));
@@ -296,9 +302,29 @@
if (throttle[i].percent_of_clock)
count++;
}
+
+ /* 0% throttled really doesn't count */
count--;
- if (count > 0)
- printk(KERN_INFO "ACPI: %d throttling states\n", count);
+
+ if (count > 0) {
+ DEBUG_PRINT(ACPI_INFO, ("%d throttling states\n", count));
+ }
+
+ return AE_OK;
+}
+
+static int
+acpi_pm_timer_init(void)
+{
+ FADT_DESCRIPTOR *fadt = &acpi_fadt;
+
+ if (fadt->tmr_val_ext) {
+ acpi_pm_tmr_len = 32;
+ } else {
+ acpi_pm_tmr_len = 24;
+ }
+
+ DEBUG_PRINT(ACPI_INFO, ("PM Timer width: %d bits\n", acpi_pm_tmr_len));
return AE_OK;
}
@@ -309,9 +335,12 @@
acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX,
- acpi_find_cpu,
+ acpi_found_cpu,
NULL,
NULL);
+
+ acpi_pm_timer_init();
+
#ifdef CONFIG_SMP
if (smp_num_cpus == 1)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)