patch-2.4.6 linux/drivers/acpi/cpu.c
Next file: linux/drivers/acpi/debugger/dbcmds.c
Previous file: linux/drivers/acpi/common/cmxface.c
Back to the patch index
Back to the overall index
- Lines: 354
- Date:
Wed Dec 31 16:00:00 1969
- Orig file:
v2.4.5/linux/drivers/acpi/cpu.c
- Orig date:
Fri Feb 9 11:45:58 2001
diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/cpu.c linux/drivers/acpi/cpu.c
@@ -1,353 +0,0 @@
-/*
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/pm.h>
-#include <linux/acpi.h>
-#include "acpi.h"
-#include "driver.h"
-
-#define _COMPONENT OS_DEPENDENT
- MODULE_NAME ("cpu")
-
-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 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 = 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, 1);
-}
-
-/*
- * Returns 1 if there has been busmaster activity
- */
-static inline int
-acpi_bm_activity(void)
-{
- 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(void)
-{
- 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(void)
-{
- acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0);
-}
-
-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)
- */
-static void
-acpi_idle(void)
-{
- static int sleep_level = 1;
- FADT_DESCRIPTOR *fadt = &acpi_fadt;
-
- /*
- * start from the previous sleep level.
- * if not initialized, we goto sleep1
- */
- if (sleep_level == 1
- || acpi_max_c_state < 2)
- goto sleep1;
-
- if (sleep_level == 2
- || acpi_max_c_state < 3)
- goto sleep2;
-
-sleep3:
- sleep_level = 3;
- if (!acpi_c3_tested) {
- DEBUG_PRINT(ACPI_INFO, ("C3 works\n"));
- acpi_c3_tested = 1;
- }
- acpi_wake_on_busmaster();
- if (fadt->Xpm2_cnt_blk.address)
- goto sleep3_with_arbiter;
-
- for (;;) {
- unsigned long time;
- unsigned long diff;
-
- __cli();
- if (current->need_resched)
- goto out;
- if (acpi_bm_activity())
- 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();
- diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
-
- __sti();
- if (diff < acpi_c3_exit_latency)
- goto sleep1;
- }
-
-sleep3_with_arbiter:
- for (;;) {
- unsigned long time;
- unsigned long diff;
-
- __cli();
- if (current->need_resched)
- goto out;
- if (acpi_bm_activity())
- goto sleep2;
-
- time = acpi_read_pm_timer();
-
- /* 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();
- diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
- /* Enable arbiter again.. */
- acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 0);
-
- __sti();
- if (diff < acpi_c3_exit_latency)
- goto sleep1;
- }
-
-sleep2:
- sleep_level = 2;
- if (!acpi_c2_tested) {
- DEBUG_PRINT(ACPI_INFO, ("C2 works\n"));
- acpi_c2_tested = 1;
- }
- acpi_wake_on_busmaster(); /* Required to track BM activity.. */
- for (;;) {
- unsigned long time;
- unsigned long diff;
-
- __cli();
- if (current->need_resched)
- 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();
- diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
-
- __sti();
- if (diff < acpi_c2_exit_latency)
- goto sleep1;
- if (acpi_bm_activity()) {
- acpi_clear_bm_activity();
- continue;
- }
- if (diff > acpi_c3_enter_latency
- && acpi_max_c_state >= 3)
- goto sleep3;
- }
-
-sleep1:
- sleep_level = 1;
- acpi_sleep_on_busmaster();
- for (;;) {
- unsigned long time;
- unsigned long diff;
-
- __cli();
- 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
- && acpi_max_c_state >= 2)
- goto sleep2;
- }
-
-out:
- __sti();
-}
-
-/*
- * Get processor information
- */
-static ACPI_STATUS
-acpi_found_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
-{
- ACPI_OBJECT obj;
- ACPI_BUFFER buf;
-
- buf.length = sizeof(obj);
- buf.pointer = &obj;
- if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf)))
- return AE_OK;
-
- 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)
- return AE_OK;
-
- acpi_pblk = obj.processor.pblk_address;
-
- if (acpi_fadt.plvl2_lat
- && acpi_fadt.plvl2_lat <= MAX_C2_LATENCY) {
- acpi_c2_exit_latency
- = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat);
- acpi_c2_enter_latency
- = 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 * 12);
- acpi_max_c_state = 3;
-
- printk(" C3");
- }
-
- 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;
-}
-
-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;
-}
-
-int
-acpi_cpu_init(void)
-{
- acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
- ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX,
- acpi_found_cpu,
- NULL,
- NULL);
-
- acpi_pm_timer_init();
-
- if (acpi_use_idle) {
-#ifdef CONFIG_SMP
- if (smp_num_cpus == 1)
- pm_idle = acpi_idle;
-#else
- 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)