- Kai Germaschewski: ISDN update (including Makefiles)
[davej-history.git] / drivers / acpi / driver.c
blob7173cb817d0bdd670e212e3e01409c5d4047f09e
1 /*
2 * driver.c - ACPI driver
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/module.h>
23 #include <linux/init.h>
24 #include <linux/kernel.h>
25 #include <linux/types.h>
26 #include <linux/slab.h>
27 #include <linux/proc_fs.h>
28 #include <linux/sysctl.h>
29 #include <linux/pm.h>
30 #include <linux/acpi.h>
31 #include <asm/uaccess.h>
32 #include "acpi.h"
33 #include "driver.h"
35 #define _COMPONENT OS_DEPENDENT
36 MODULE_NAME ("driver")
38 struct acpi_run_entry
40 void (*callback)(void*);
41 void *context;
42 struct tq_struct task;
45 static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED;
46 static volatile u32 acpi_event_status = 0;
47 static volatile acpi_sstate_t acpi_event_state = ACPI_S0;
48 static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait);
50 static volatile int acpi_thread_pid = -1;
52 /************************************************/
53 /* DECLARE_TASK_QUEUE is defined in */
54 /* /usr/src/linux/include/linux/tqueue.h */
55 /* So, acpi_thread_run is a pointer to a */
56 /* tq_struct structure,defined in the same file.*/
57 /************************************************/
58 static DECLARE_TASK_QUEUE(acpi_thread_run);
60 static DECLARE_WAIT_QUEUE_HEAD(acpi_thread_wait);
62 static struct ctl_table_header *acpi_sysctl = NULL;
65 * Examine/modify value
67 static int
68 acpi_do_ulong(ctl_table * ctl,
69 int write,
70 struct file *file,
71 void *buffer,
72 size_t * len)
74 char str[2 * sizeof(unsigned long) + 4], *strend;
75 unsigned long val;
76 int size;
78 if (!write) {
79 if (file->f_pos) {
80 *len = 0;
81 return 0;
84 val = *(unsigned long *) ctl->data;
85 size = sprintf(str, "0x%08lx\n", val);
86 if (*len >= size) {
87 copy_to_user(buffer, str, size);
88 *len = size;
90 else
91 *len = 0;
93 else {
94 size = sizeof(str) - 1;
95 if (size > *len)
96 size = *len;
97 copy_from_user(str, buffer, size);
98 str[size] = '\0';
99 val = simple_strtoul(str, &strend, 0);
100 if (strend == str)
101 return -EINVAL;
102 *(unsigned long *) ctl->data = val;
105 file->f_pos += *len;
106 return 0;
109 static int
110 acpi_do_pm_timer(ctl_table * ctl,
111 int write,
112 struct file *file,
113 void *buffer,
114 size_t * len)
116 int size;
117 u32 val = 0;
119 char str[12];
121 if (file->f_pos) {
122 *len = 0;
123 return 0;
126 val = acpi_read_pm_timer();
128 size = sprintf(str, "0x%08x\n", val);
129 if (*len >= size) {
130 copy_to_user(buffer, str, size);
131 *len = size;
133 else
134 *len = 0;
136 file->f_pos += *len;
138 return 0;
142 * Handle ACPI event
144 static u32
145 acpi_event(void *context)
147 unsigned long flags;
148 int event = (int)(long)context;
149 int mask = 0;
151 switch (event) {
152 case ACPI_EVENT_POWER_BUTTON:
153 mask = ACPI_PWRBTN;
154 break;
155 case ACPI_EVENT_SLEEP_BUTTON:
156 mask = ACPI_SLPBTN;
157 break;
158 default:
159 return AE_ERROR;
162 if (mask) {
163 // notify process waiting on /dev/acpi
164 spin_lock_irqsave(&acpi_event_lock, flags);
165 acpi_event_status |= mask;
166 spin_unlock_irqrestore(&acpi_event_lock, flags);
167 acpi_event_state = acpi_sleep_state;
168 wake_up_interruptible(&acpi_event_wait);
171 return AE_OK;
175 * Wait for next event
177 static int
178 acpi_do_event(ctl_table * ctl,
179 int write,
180 struct file *file,
181 void *buffer,
182 size_t * len)
184 u32 event_status = 0;
185 acpi_sstate_t event_state = 0;
186 char str[27];
187 int size;
189 if (write)
190 return -EPERM;
191 if (*len < sizeof(str)) {
192 *len = 0;
193 return 0;
196 for (;;) {
197 unsigned long flags;
199 // we need an atomic exchange here
200 spin_lock_irqsave(&acpi_event_lock, flags);
201 event_status = acpi_event_status;
202 acpi_event_status = 0;
203 spin_unlock_irqrestore(&acpi_event_lock, flags);
204 event_state = acpi_event_state;
206 if (event_status)
207 break;
209 // wait for an event to arrive
210 interruptible_sleep_on(&acpi_event_wait);
211 if (signal_pending(current))
212 return -ERESTARTSYS;
215 size = sprintf(str,
216 "0x%08x 0x%08x 0x%01x\n",
217 event_status,
219 event_state);
220 copy_to_user(buffer, str, size);
221 *len = size;
222 file->f_pos += size;
224 return 0;
228 * Enter system sleep state
230 static int
231 acpi_do_sleep(ctl_table * ctl,
232 int write,
233 struct file *file,
234 void *buffer,
235 size_t * len)
237 if (!write) {
238 if (file->f_pos) {
239 *len = 0;
240 return 0;
243 else {
244 int status = acpi_enter_sx(ACPI_S1);
245 if (status)
246 return status;
248 file->f_pos += *len;
249 return 0;
254 * Output important ACPI tables to proc
256 static int
257 acpi_do_table(ctl_table * ctl,
258 int write,
259 struct file *file,
260 void *buffer,
261 size_t * len)
263 u32 table_type;
264 size_t size;
265 ACPI_BUFFER buf;
266 u8* data;
268 table_type = (u32) ctl->data;
269 size = 0;
270 buf.length = 0;
271 buf.pointer = NULL;
273 /* determine what buffer size we will need */
274 if (acpi_get_table(table_type, 1, &buf) != AE_BUFFER_OVERFLOW) {
275 *len = 0;
276 return 0;
279 buf.pointer = kmalloc(buf.length, GFP_KERNEL);
280 if (!buf.pointer) {
281 return -ENOMEM;
284 /* get the table for real */
285 if (!ACPI_SUCCESS(acpi_get_table(table_type, 1, &buf))) {
286 kfree(buf.pointer);
287 *len = 0;
288 return 0;
291 if (file->f_pos < buf.length) {
292 data = buf.pointer + file->f_pos;
293 size = buf.length - file->f_pos;
294 if (size > *len)
295 size = *len;
296 if (copy_to_user(buffer, data, size))
297 return -EFAULT;
300 kfree(buf.pointer);
302 *len = size;
303 file->f_pos += size;
304 return 0;
307 /********************************************************************/
308 /* R U N Q U E U E D C A L L B A C K */
309 /* */
310 /* The "callback" function address that was tramped through via */
311 /* "acpi_run" below is finally called and executed. If we trace all */
312 /* this down, the function is acpi_ev_asynch_execute_gpe_method, in */
313 /* evevent.c The only other function that is ever queued is */
314 /* acpi_ev_global_lock_thread in evmisc.c. */
315 /********************************************************************/
316 static void
317 acpi_run_exec(void *context)
319 struct acpi_run_entry *entry
320 = (struct acpi_run_entry*) context;
321 (*entry->callback)(entry->context);
322 kfree(entry);
326 * Queue for execution by the ACPI thread
329 acpi_run(void (*callback)(void*), void *context)
331 struct acpi_run_entry *entry;
333 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
334 if (!entry)
335 return -1;
337 memset(entry, 0, sizeof(entry));
338 entry->callback = callback;
339 entry->context = context;
340 entry->task.routine = acpi_run_exec;
341 entry->task.data = entry;
343 queue_task(&entry->task, &acpi_thread_run);
345 if (waitqueue_active(&acpi_thread_wait))
346 wake_up(&acpi_thread_wait);
348 return 0;
351 static struct ctl_table acpi_table[] =
353 {ACPI_P_LVL2_LAT, "c2_exit_latency",
354 &acpi_c2_exit_latency, sizeof(acpi_c2_exit_latency),
355 0644, NULL, &acpi_do_ulong},
357 {ACPI_ENTER_LVL2_LAT, "c2_enter_latency",
358 &acpi_c2_enter_latency, sizeof(acpi_c2_enter_latency),
359 0644, NULL, &acpi_do_ulong},
361 {ACPI_P_LVL3_LAT, "c3_exit_latency",
362 &acpi_c3_exit_latency, sizeof(acpi_c3_exit_latency),
363 0644, NULL, &acpi_do_ulong},
365 {ACPI_ENTER_LVL3_LAT, "c3_enter_latency",
366 &acpi_c3_enter_latency, sizeof(acpi_c3_enter_latency),
367 0644, NULL, &acpi_do_ulong},
369 {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep},
371 {ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event},
373 {ACPI_FADT, "fadt", (void *) ACPI_TABLE_FADT, sizeof(int),
374 0444, NULL, &acpi_do_table},
376 {ACPI_DSDT, "dsdt", (void *) ACPI_TABLE_DSDT, sizeof(int),
377 0444, NULL, &acpi_do_table},
379 {ACPI_FACS, "facs", (void *) ACPI_TABLE_FACS, sizeof(int),
380 0444, NULL, &acpi_do_table},
382 {ACPI_XSDT, "xsdt", (void *) ACPI_TABLE_XSDT, sizeof(int),
383 0444, NULL, &acpi_do_table},
385 {ACPI_PMTIMER, "pm_timer", NULL, 0, 0444, NULL, &acpi_do_pm_timer},
390 static struct ctl_table acpi_dir_table[] =
392 {CTL_ACPI, "acpi", NULL, 0, 0555, acpi_table},
397 * Initialize and run interpreter within a kernel thread
399 static int
400 acpi_thread(void *context)
402 ACPI_PHYSICAL_ADDRESS rsdp_phys;
405 * initialize
407 daemonize();
408 strcpy(current->comm, "kacpid");
410 if (!ACPI_SUCCESS(acpi_initialize_subsystem())) {
411 printk(KERN_ERR "ACPI: Driver initialization failed\n");
412 return -ENODEV;
415 /* arch-specific call to get rsdp ptr */
416 rsdp_phys = acpi_get_rsdp_ptr();
417 if (!rsdp_phys) {
418 printk(KERN_ERR "ACPI: System description tables not found\n");
419 return -ENODEV;
422 printk(KERN_ERR "ACPI: System description tables found\n");
424 if (!ACPI_SUCCESS(acpi_find_and_load_tables(rsdp_phys)))
425 return -ENODEV;
427 if (PM_IS_ACTIVE()) {
428 printk(KERN_NOTICE "ACPI: APM is already active, exiting\n");
429 acpi_terminate();
430 return -ENODEV;
433 if (!ACPI_SUCCESS(acpi_enable_subsystem(ACPI_FULL_INITIALIZATION))) {
434 printk(KERN_ERR "ACPI: Subsystem enable failed\n");
435 acpi_terminate();
436 return -ENODEV;
439 printk(KERN_ERR "ACPI: Subsystem enabled\n");
441 pm_active = 1;
443 acpi_cpu_init();
444 acpi_sys_init();
445 acpi_ec_init();
446 acpi_cmbatt_init();
449 * Non-intuitive: 0 means pwr and sleep are implemented using the fixed
450 * feature model, so we install handlers. 1 means a control method
451 * implementation, or none at all, so do nothing. See ACPI spec.
453 if (acpi_fadt.pwr_button == 0) {
454 if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
455 ACPI_EVENT_POWER_BUTTON,
456 acpi_event,
457 (void *) ACPI_EVENT_POWER_BUTTON))) {
458 printk(KERN_ERR "ACPI: power button enable failed\n");
462 if (acpi_fadt.sleep_button == 0) {
463 if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
464 ACPI_EVENT_SLEEP_BUTTON,
465 acpi_event,
466 (void *) ACPI_EVENT_SLEEP_BUTTON))) {
467 printk(KERN_ERR "ACPI: sleep button enable failed\n");
471 acpi_sysctl = register_sysctl_table(acpi_dir_table, 1);
474 * run
476 for (;;) {
477 interruptible_sleep_on(&acpi_thread_wait);
478 if (signal_pending(current))
479 break;
480 run_task_queue(&acpi_thread_run);
484 * terminate
486 unregister_sysctl_table(acpi_sysctl);
488 /* do not terminate, because we need acpi in order to shut down */
489 /*acpi_terminate();*/
491 acpi_thread_pid = -1;
493 return 0;
497 * Start the interpreter
499 int __init
500 acpi_init(void)
502 acpi_thread_pid = kernel_thread(acpi_thread,
503 NULL,
504 (CLONE_FS | CLONE_FILES
505 | CLONE_SIGHAND | SIGCHLD));
506 return ((acpi_thread_pid >= 0) ? 0:-ENODEV);
510 * Terminate the interpreter
512 void __exit
513 acpi_exit(void)
515 int count;
517 if (!kill_proc(acpi_thread_pid, SIGTERM, 1)) {
518 // wait until thread terminates (at most 5 seconds)
519 count = 5 * HZ;
520 while (acpi_thread_pid >= 0 && --count) {
521 current->state = TASK_INTERRUPTIBLE;
522 schedule_timeout(1);
526 pm_idle = NULL;
527 pm_power_off = NULL;
528 pm_active = 0;
531 module_init(acpi_init);
532 module_exit(acpi_exit);