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>
30 #include <linux/acpi.h>
31 #include <asm/uaccess.h>
35 #define _COMPONENT OS_DEPENDENT
36 MODULE_NAME ("driver")
40 void (*callback
)(void*);
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
68 acpi_do_ulong(ctl_table
* ctl
,
74 char str
[2 * sizeof(unsigned long) + 4], *strend
;
84 val
= *(unsigned long *) ctl
->data
;
85 size
= sprintf(str
, "0x%08lx\n", val
);
87 copy_to_user(buffer
, str
, size
);
94 size
= sizeof(str
) - 1;
97 copy_from_user(str
, buffer
, size
);
99 val
= simple_strtoul(str
, &strend
, 0);
102 *(unsigned long *) ctl
->data
= val
;
110 acpi_do_pm_timer(ctl_table
* ctl
,
126 val
= acpi_read_pm_timer();
128 size
= sprintf(str
, "0x%08x\n", val
);
130 copy_to_user(buffer
, str
, size
);
145 acpi_event(void *context
)
148 int event
= (int)(long)context
;
152 case ACPI_EVENT_POWER_BUTTON
:
155 case ACPI_EVENT_SLEEP_BUTTON
:
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
);
175 * Wait for next event
178 acpi_do_event(ctl_table
* ctl
,
184 u32 event_status
= 0;
185 acpi_sstate_t event_state
= 0;
191 if (*len
< sizeof(str
)) {
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
;
209 // wait for an event to arrive
210 interruptible_sleep_on(&acpi_event_wait
);
211 if (signal_pending(current
))
216 "0x%08x 0x%08x 0x%01x\n",
220 copy_to_user(buffer
, str
, size
);
228 * Enter system sleep state
231 acpi_do_sleep(ctl_table
* ctl
,
244 int status
= acpi_enter_sx(ACPI_S1
);
254 * Output important ACPI tables to proc
257 acpi_do_table(ctl_table
* ctl
,
268 table_type
= (u32
) ctl
->data
;
273 /* determine what buffer size we will need */
274 if (acpi_get_table(table_type
, 1, &buf
) != AE_BUFFER_OVERFLOW
) {
279 buf
.pointer
= kmalloc(buf
.length
, GFP_KERNEL
);
284 /* get the table for real */
285 if (!ACPI_SUCCESS(acpi_get_table(table_type
, 1, &buf
))) {
291 if (file
->f_pos
< buf
.length
) {
292 data
= buf
.pointer
+ file
->f_pos
;
293 size
= buf
.length
- file
->f_pos
;
296 if (copy_to_user(buffer
, data
, size
))
307 /********************************************************************/
308 /* R U N Q U E U E D C A L L B A C K */
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 /********************************************************************/
317 acpi_run_exec(void *context
)
319 struct acpi_run_entry
*entry
320 = (struct acpi_run_entry
*) context
;
321 (*entry
->callback
)(entry
->context
);
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
);
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
);
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
400 acpi_thread(void *context
)
402 ACPI_PHYSICAL_ADDRESS rsdp_phys
;
408 strcpy(current
->comm
, "kacpid");
410 if (!ACPI_SUCCESS(acpi_initialize_subsystem())) {
411 printk(KERN_ERR
"ACPI: Driver initialization failed\n");
415 /* arch-specific call to get rsdp ptr */
416 rsdp_phys
= acpi_get_rsdp_ptr();
418 printk(KERN_ERR
"ACPI: System description tables not found\n");
422 printk(KERN_ERR
"ACPI: System description tables found\n");
424 if (!ACPI_SUCCESS(acpi_find_and_load_tables(rsdp_phys
)))
427 if (PM_IS_ACTIVE()) {
428 printk(KERN_NOTICE
"ACPI: APM is already active, exiting\n");
433 if (!ACPI_SUCCESS(acpi_enable_subsystem(ACPI_FULL_INITIALIZATION
))) {
434 printk(KERN_ERR
"ACPI: Subsystem enable failed\n");
439 printk(KERN_ERR
"ACPI: Subsystem enabled\n");
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
,
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
,
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);
477 interruptible_sleep_on(&acpi_thread_wait
);
478 if (signal_pending(current
))
480 run_task_queue(&acpi_thread_run
);
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;
497 * Start the interpreter
502 acpi_thread_pid
= kernel_thread(acpi_thread
,
504 (CLONE_FS
| CLONE_FILES
505 | CLONE_SIGHAND
| SIGCHLD
));
506 return ((acpi_thread_pid
>= 0) ? 0:-ENODEV
);
510 * Terminate the interpreter
517 if (!kill_proc(acpi_thread_pid
, SIGTERM
, 1)) {
518 // wait until thread terminates (at most 5 seconds)
520 while (acpi_thread_pid
>= 0 && --count
) {
521 current
->state
= TASK_INTERRUPTIBLE
;
531 module_init(acpi_init
);
532 module_exit(acpi_exit
);