- Kai Germaschewski: ISDN update (including Makefiles)
[davej-history.git] / drivers / acpi / cpu.c
blob00ec59da52149da8c6562b5f9506a52eb7e2569e
1 /*
2 * cpu.c - Processor handling
4 * Copyright (C) 2000 Andrew Henroid
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/config.h>
22 #include <linux/kernel.h>
23 #include <linux/pm.h>
24 #include <linux/acpi.h>
25 #include "acpi.h"
26 #include "driver.h"
28 #define _COMPONENT OS_DEPENDENT
29 MODULE_NAME ("cpu")
31 unsigned long acpi_c2_exit_latency = ACPI_INFINITE;
32 unsigned long acpi_c3_exit_latency = ACPI_INFINITE;
33 unsigned long acpi_c2_enter_latency = ACPI_INFINITE;
34 unsigned long acpi_c3_enter_latency = ACPI_INFINITE;
36 static unsigned long acpi_pblk = ACPI_INVALID;
37 static int acpi_c2_tested = 0;
38 static int acpi_c3_tested = 0;
39 static int acpi_max_c_state = 1;
40 static int acpi_pm_tmr_len;
43 * Clear busmaster activity flag
45 static inline void
46 acpi_clear_bm_activity(void)
48 acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 0);
52 * Returns 1 if there has been busmaster activity
54 static inline int
55 acpi_bm_activity(void)
57 return acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, BM_STS);
61 * Set system to sleep through busmaster requests
63 static void
64 acpi_sleep_on_busmaster(void)
66 acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1);
70 * Set system to wake on busmaster requests
72 static void
73 acpi_wake_on_busmaster(void)
75 acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0);
78 u32
79 acpi_read_pm_timer(void)
81 return acpi_hw_register_read(ACPI_MTX_LOCK, PM_TIMER);
85 * Do a compare, accounting for 24/32bit rollover
87 static u32
88 acpi_compare_pm_timers(u32 first, u32 second)
90 if (first < second) {
91 return (second - first);
92 } else {
93 if (acpi_pm_tmr_len == 24)
94 return (second + (0xFFFFFF - first));
95 else
96 return (second + (0xFFFFFFFF - first));
101 * Idle loop (uniprocessor only)
103 static void
104 acpi_idle(void)
106 static int sleep_level = 1;
107 FADT_DESCRIPTOR *fadt = &acpi_fadt;
109 if (!fadt
110 || (STRNCMP(fadt->header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0)
111 || !fadt->Xpm_tmr_blk.address
112 || !acpi_pblk)
113 goto not_initialized;
116 * start from the previous sleep level..
118 if (sleep_level == 1
119 || acpi_max_c_state < 2)
120 goto sleep1;
122 if (sleep_level == 2
123 || acpi_max_c_state < 3)
124 goto sleep2;
126 sleep3:
127 sleep_level = 3;
128 if (!acpi_c3_tested) {
129 DEBUG_PRINT(ACPI_INFO, ("C3 works\n"));
130 acpi_c3_tested = 1;
132 acpi_wake_on_busmaster();
133 if (fadt->Xpm2_cnt_blk.address)
134 goto sleep3_with_arbiter;
136 for (;;) {
137 unsigned long time;
138 unsigned long diff;
140 __cli();
141 if (current->need_resched)
142 goto out;
143 if (acpi_bm_activity())
144 goto sleep2;
146 time = acpi_read_pm_timer();
147 inb(acpi_pblk + ACPI_P_LVL3);
148 /* Dummy read, force synchronization with the PMU */
149 acpi_read_pm_timer();
150 diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
152 __sti();
153 if (diff < acpi_c3_exit_latency)
154 goto sleep2;
157 sleep3_with_arbiter:
158 for (;;) {
159 unsigned long time;
160 unsigned long diff;
162 __cli();
163 if (current->need_resched)
164 goto out;
165 if (acpi_bm_activity())
166 goto sleep2;
168 time = acpi_read_pm_timer();
170 /* Disable arbiter, park on CPU */
171 acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 1);
172 inb(acpi_pblk + ACPI_P_LVL3);
173 /* Dummy read, force synchronization with the PMU */
174 acpi_read_pm_timer();
175 diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
176 /* Enable arbiter again.. */
177 acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 0);
179 __sti();
180 if (diff < acpi_c3_exit_latency)
181 goto sleep2;
184 sleep2:
185 sleep_level = 2;
186 if (!acpi_c2_tested) {
187 DEBUG_PRINT(ACPI_INFO, ("C2 works\n"));
188 acpi_c2_tested = 1;
190 acpi_wake_on_busmaster(); /* Required to track BM activity.. */
191 for (;;) {
192 unsigned long time;
193 unsigned long diff;
195 __cli();
196 if (current->need_resched)
197 goto out;
199 time = acpi_read_pm_timer();
200 inb(acpi_pblk + ACPI_P_LVL2);
201 /* Dummy read, force synchronization with the PMU */
202 acpi_read_pm_timer();
203 diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
205 __sti();
206 if (diff < acpi_c2_exit_latency)
207 goto sleep1;
208 if (acpi_bm_activity()) {
209 acpi_clear_bm_activity();
210 continue;
212 if (diff > acpi_c3_enter_latency
213 && acpi_max_c_state >= 3)
214 goto sleep3;
217 sleep1:
218 sleep_level = 1;
219 acpi_sleep_on_busmaster();
220 for (;;) {
221 unsigned long time;
222 unsigned long diff;
224 __cli();
225 if (current->need_resched)
226 goto out;
227 time = acpi_read_pm_timer();
228 safe_halt();
229 diff = acpi_compare_pm_timers(time, acpi_read_pm_timer());
230 if (diff > acpi_c2_enter_latency
231 && acpi_max_c_state >= 2)
232 goto sleep2;
235 not_initialized:
236 for (;;) {
237 __cli();
238 if (current->need_resched)
239 goto out;
240 safe_halt();
243 out:
244 __sti();
248 * Get processor information
250 static ACPI_STATUS
251 acpi_found_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
253 ACPI_OBJECT obj;
254 ACPI_CX_STATE lat[4];
255 ACPI_CPU_THROTTLING_STATE throttle[ACPI_MAX_THROTTLE];
256 ACPI_BUFFER buf;
257 int i, count;
259 buf.length = sizeof(obj);
260 buf.pointer = &obj;
261 if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf)))
262 return AE_OK;
264 DEBUG_PRINT(ACPI_INFO, ("PBLK %d @ 0x%04x:%d\n",
265 obj.processor.proc_id,
266 obj.processor.pblk_address,
267 obj.processor.pblk_length));
269 if (acpi_pblk != ACPI_INVALID
270 || !obj.processor.pblk_address
271 || obj.processor.pblk_length != 6)
272 return AE_OK;
274 acpi_pblk = obj.processor.pblk_address;
276 buf.length = sizeof(lat);
277 buf.pointer = lat;
278 if (!ACPI_SUCCESS(acpi_get_processor_cx_info(handle, &buf)))
279 return AE_OK;
281 if (lat[2].latency < MAX_CX_STATE_LATENCY) {
282 printk(KERN_INFO "ACPI: System firmware supports: C2");
283 acpi_c2_exit_latency = lat[2].latency;
284 acpi_max_c_state = 2;
286 if (lat[3].latency < MAX_CX_STATE_LATENCY) {
287 printk(" C3");
288 acpi_c3_exit_latency = lat[3].latency;
289 acpi_max_c_state = 3;
291 printk("\n");
294 memset(throttle, 0, sizeof(throttle));
295 buf.length = sizeof(throttle);
296 buf.pointer = throttle;
298 if (!ACPI_SUCCESS(acpi_get_processor_throttling_info(handle, &buf)))
299 return AE_OK;
301 for (i = 0, count = 0; i < ACPI_MAX_THROTTLE; i++) {
302 if (throttle[i].percent_of_clock)
303 count++;
306 /* 0% throttled really doesn't count */
307 count--;
309 if (count > 0) {
310 DEBUG_PRINT(ACPI_INFO, ("%d throttling states\n", count));
313 return AE_OK;
316 static int
317 acpi_pm_timer_init(void)
319 FADT_DESCRIPTOR *fadt = &acpi_fadt;
321 if (fadt->tmr_val_ext) {
322 acpi_pm_tmr_len = 32;
323 } else {
324 acpi_pm_tmr_len = 24;
327 DEBUG_PRINT(ACPI_INFO, ("PM Timer width: %d bits\n", acpi_pm_tmr_len));
329 return AE_OK;
333 acpi_cpu_init(void)
335 acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
336 ACPI_ROOT_OBJECT,
337 ACPI_UINT32_MAX,
338 acpi_found_cpu,
339 NULL,
340 NULL);
342 acpi_pm_timer_init();
345 #ifdef CONFIG_SMP
346 if (smp_num_cpus == 1)
347 pm_idle = acpi_idle;
348 #else
349 pm_idle = acpi_idle;
350 #endif
352 return 0;