This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / acpi / bus.c
1 /*
2  *  acpi_bus.c - ACPI Bus Driver ($Revision: 80 $)
3  *
4  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
5  *
6  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or (at
11  *  your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful, but
14  *  WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License along
19  *  with this program; if not, write to the Free Software Foundation, Inc.,
20  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21  *
22  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23  */
24
25 #include <linux/init.h>
26 #include <linux/ioport.h>
27 #include <linux/list.h>
28 #include <linux/sched.h>
29 #include <linux/pm.h>
30 #include <linux/device.h>
31 #include <linux/proc_fs.h>
32 #include <linux/reboot.h>
33 #ifdef CONFIG_X86
34 #include <asm/mpspec.h>
35 #endif
36 #include <acpi/acpi_bus.h>
37 #include <acpi/acpi_drivers.h>
38
39
40 #define _COMPONENT              ACPI_BUS_COMPONENT
41 ACPI_MODULE_NAME                ("acpi_bus")
42
43 #ifdef  CONFIG_X86
44 extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
45 #endif
46
47 FADT_DESCRIPTOR                 acpi_fadt;
48 struct acpi_device              *acpi_root;
49 struct proc_dir_entry           *acpi_root_dir;
50
51 #define STRUCT_TO_INT(s)        (*((int*)&s))
52
53 /* --------------------------------------------------------------------------
54                                 Device Management
55    -------------------------------------------------------------------------- */
56
57 extern void acpi_bus_data_handler (
58         acpi_handle             handle,
59         u32                     function,
60         void                    *context);
61 int
62 acpi_bus_get_device (
63         acpi_handle             handle,
64         struct acpi_device      **device)
65 {
66         acpi_status             status = AE_OK;
67
68         ACPI_FUNCTION_TRACE("acpi_bus_get_device");
69
70         if (!device)
71                 return_VALUE(-EINVAL);
72
73         /* TBD: Support fixed-feature devices */
74
75         status = acpi_get_data(handle, acpi_bus_data_handler, (void**) device);
76         if (ACPI_FAILURE(status) || !*device) {
77                 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error getting context for object [%p]\n",
78                         handle));
79                 return_VALUE(-ENODEV);
80         }
81
82         return_VALUE(0);
83 }
84
85 int
86 acpi_bus_get_status (
87         struct acpi_device      *device)
88 {
89         acpi_status             status = AE_OK;
90         unsigned long           sta = 0;
91         
92         ACPI_FUNCTION_TRACE("acpi_bus_get_status");
93
94         if (!device)
95                 return_VALUE(-EINVAL);
96
97         /*
98          * Evaluate _STA if present.
99          */
100         if (device->flags.dynamic_status) {
101                 status = acpi_evaluate_integer(device->handle, "_STA", NULL, &sta);
102                 if (ACPI_FAILURE(status))
103                         return_VALUE(-ENODEV);
104                 STRUCT_TO_INT(device->status) = (int) sta;
105         }
106
107         /*
108          * Otherwise we assume the status of our parent (unless we don't
109          * have one, in which case status is implied).
110          */
111         else if (device->parent)
112                 device->status = device->parent->status;
113         else
114                 STRUCT_TO_INT(device->status) = 0x0F;
115
116         if (device->status.functional && !device->status.present) {
117                 printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
118                         "functional but not present; setting present\n",
119                         device->pnp.bus_id,
120                         (u32) STRUCT_TO_INT(device->status));
121                 device->status.present = 1;
122         }
123
124         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", 
125                 device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status)));
126
127         return_VALUE(0);
128 }
129
130
131 /* --------------------------------------------------------------------------
132                                  Power Management
133    -------------------------------------------------------------------------- */
134
135 int
136 acpi_bus_get_power (
137         acpi_handle             handle,
138         int                     *state)
139 {
140         int                     result = 0;
141         acpi_status             status = 0;
142         struct acpi_device      *device = NULL;
143         unsigned long           psc = 0;
144
145         ACPI_FUNCTION_TRACE("acpi_bus_get_power");
146
147         result = acpi_bus_get_device(handle, &device);
148         if (result)
149                 return_VALUE(result);
150
151         *state = ACPI_STATE_UNKNOWN;
152
153         if (!device->flags.power_manageable) {
154                 /* TBD: Non-recursive algorithm for walking up hierarchy */
155                 if (device->parent)
156                         *state = device->parent->power.state;
157                 else
158                         *state = ACPI_STATE_D0;
159         }
160         else {
161                 /*
162                  * Get the device's power state either directly (via _PSC) or 
163                  * indirectly (via power resources).
164                  */
165                 if (device->power.flags.explicit_get) {
166                         status = acpi_evaluate_integer(device->handle, "_PSC", 
167                                 NULL, &psc);
168                         if (ACPI_FAILURE(status))
169                                 return_VALUE(-ENODEV);
170                         device->power.state = (int) psc;
171                 }
172                 else if (device->power.flags.power_resources) {
173                         result = acpi_power_get_inferred_state(device);
174                         if (result)
175                                 return_VALUE(result);
176                 }
177
178                 *state = device->power.state;
179         }
180
181         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
182                 device->pnp.bus_id, device->power.state));
183
184         return_VALUE(0);
185 }
186
187
188 int
189 acpi_bus_set_power (
190         acpi_handle             handle,
191         int                     state)
192 {
193         int                     result = 0;
194         acpi_status             status = AE_OK;
195         struct acpi_device      *device = NULL;
196         char                    object_name[5] = {'_','P','S','0'+state,'\0'};
197
198         ACPI_FUNCTION_TRACE("acpi_bus_set_power");
199
200         result = acpi_bus_get_device(handle, &device);
201         if (result)
202                 return_VALUE(result);
203
204         if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
205                 return_VALUE(-EINVAL);
206
207         /* Make sure this is a valid target state */
208
209         if (!device->flags.power_manageable) {
210                 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device is not power manageable\n"));
211                 return_VALUE(-ENODEV);
212         }
213         if (state == device->power.state) {
214                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", state));
215                 return_VALUE(0);
216         }
217         if (!device->power.states[state].flags.valid) {
218                 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n", state));
219                 return_VALUE(-ENODEV);
220         }
221         if (device->parent && (state < device->parent->power.state)) {
222                 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Cannot set device to a higher-powered state than parent\n"));
223                 return_VALUE(-ENODEV);
224         }
225
226         /*
227          * Transition Power
228          * ----------------
229          * On transitions to a high-powered state we first apply power (via
230          * power resources) then evalute _PSx.  Conversly for transitions to
231          * a lower-powered state.
232          */ 
233         if (state < device->power.state) {
234                 if (device->power.flags.power_resources) {
235                         result = acpi_power_transition(device, state);
236                         if (result)
237                                 goto end;
238                 }
239                 if (device->power.states[state].flags.explicit_set) {
240                         status = acpi_evaluate_object(device->handle, 
241                                 object_name, NULL, NULL);
242                         if (ACPI_FAILURE(status)) {
243                                 result = -ENODEV;
244                                 goto end;
245                         }
246                 }
247         }
248         else {
249                 if (device->power.states[state].flags.explicit_set) {
250                         status = acpi_evaluate_object(device->handle, 
251                                 object_name, NULL, NULL);
252                         if (ACPI_FAILURE(status)) {
253                                 result = -ENODEV;
254                                 goto end;
255                         }
256                 }
257                 if (device->power.flags.power_resources) {
258                         result = acpi_power_transition(device, state);
259                         if (result)
260                                 goto end;
261                 }
262         }
263
264 end:
265         if (result)
266                 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Error transitioning device [%s] to D%d\n",
267                         device->pnp.bus_id, state));
268         else
269                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] transitioned to D%d\n",
270                         device->pnp.bus_id, state));
271
272         return_VALUE(result);
273 }
274
275
276
277 /* --------------------------------------------------------------------------
278                                 Event Management
279    -------------------------------------------------------------------------- */
280
281 static spinlock_t               acpi_bus_event_lock = SPIN_LOCK_UNLOCKED;
282
283 LIST_HEAD(acpi_bus_event_list);
284 DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
285
286 extern int                      event_is_open;
287
288 int
289 acpi_bus_generate_event (
290         struct acpi_device      *device,
291         u8                      type,
292         int                     data)
293 {
294         struct acpi_bus_event   *event = NULL;
295         unsigned long           flags = 0;
296
297         ACPI_FUNCTION_TRACE("acpi_bus_generate_event");
298
299         if (!device)
300                 return_VALUE(-EINVAL);
301
302         /* drop event on the floor if no one's listening */
303         if (!event_is_open)
304                 return_VALUE(0);
305
306         event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
307         if (!event)
308                 return_VALUE(-ENOMEM);
309
310         strcpy(event->device_class, device->pnp.device_class);
311         strcpy(event->bus_id, device->pnp.bus_id);
312         event->type = type;
313         event->data = data;
314
315         spin_lock_irqsave(&acpi_bus_event_lock, flags);
316         list_add_tail(&event->node, &acpi_bus_event_list);
317         spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
318
319         wake_up_interruptible(&acpi_bus_event_queue);
320
321         return_VALUE(0);
322 }
323
324 int
325 acpi_bus_receive_event (
326         struct acpi_bus_event   *event)
327 {
328         unsigned long           flags = 0;
329         struct acpi_bus_event   *entry = NULL;
330
331         DECLARE_WAITQUEUE(wait, current);
332
333         ACPI_FUNCTION_TRACE("acpi_bus_receive_event");
334
335         if (!event)
336                 return -EINVAL;
337
338         if (list_empty(&acpi_bus_event_list)) {
339
340                 set_current_state(TASK_INTERRUPTIBLE);
341                 add_wait_queue(&acpi_bus_event_queue, &wait);
342
343                 if (list_empty(&acpi_bus_event_list))
344                         schedule();
345
346                 remove_wait_queue(&acpi_bus_event_queue, &wait);
347                 set_current_state(TASK_RUNNING);
348
349                 if (signal_pending(current))
350                         return_VALUE(-ERESTARTSYS);
351         }
352
353         spin_lock_irqsave(&acpi_bus_event_lock, flags);
354         entry = list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node);
355         if (entry)
356                 list_del(&entry->node);
357         spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
358
359         if (!entry)
360                 return_VALUE(-ENODEV);
361
362         memcpy(event, entry, sizeof(struct acpi_bus_event));
363
364         kfree(entry);
365
366         return_VALUE(0);
367 }
368
369
370 /* --------------------------------------------------------------------------
371                              Notification Handling
372    -------------------------------------------------------------------------- */
373
374 static int
375 acpi_bus_check_device (
376         struct acpi_device      *device,
377         int                     *status_changed)
378 {
379         acpi_status             status = 0;
380         struct acpi_device_status old_status;
381
382         ACPI_FUNCTION_TRACE("acpi_bus_check_device");
383
384         if (!device)
385                 return_VALUE(-EINVAL);
386
387         if (status_changed)
388                 *status_changed = 0;
389
390         old_status = device->status;
391
392         /*
393          * Make sure this device's parent is present before we go about
394          * messing with the device.
395          */
396         if (device->parent && !device->parent->status.present) {
397                 device->status = device->parent->status;
398                 if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) {
399                         if (status_changed)
400                                 *status_changed = 1;
401                 }
402                 return_VALUE(0);
403         }
404
405         status = acpi_bus_get_status(device);
406         if (ACPI_FAILURE(status))
407                 return_VALUE(-ENODEV);
408
409         if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status))
410                 return_VALUE(0);
411
412         if (status_changed)
413                 *status_changed = 1;
414         
415         /*
416          * Device Insertion/Removal
417          */
418         if ((device->status.present) && !(old_status.present)) {
419                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n"));
420                 /* TBD: Handle device insertion */
421         }
422         else if (!(device->status.present) && (old_status.present)) {
423                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n"));
424                 /* TBD: Handle device removal */
425         }
426
427         return_VALUE(0);
428 }
429
430
431 static int
432 acpi_bus_check_scope (
433         struct acpi_device      *device)
434 {
435         int                     result = 0;
436         int                     status_changed = 0;
437
438         ACPI_FUNCTION_TRACE("acpi_bus_check_scope");
439
440         if (!device)
441                 return_VALUE(-EINVAL);
442
443         /* Status Change? */
444         result = acpi_bus_check_device(device, &status_changed);
445         if (result)
446                 return_VALUE(result);
447
448         if (!status_changed)
449                 return_VALUE(0);
450
451         /*
452          * TBD: Enumerate child devices within this device's scope and
453          *       run acpi_bus_check_device()'s on them.
454          */
455
456         return_VALUE(0);
457 }
458
459
460 /**
461  * acpi_bus_notify
462  * ---------------
463  * Callback for all 'system-level' device notifications (values 0x00-0x7F).
464  */
465 static void 
466 acpi_bus_notify (
467         acpi_handle             handle,
468         u32                     type,
469         void                    *data)
470 {
471         int                     result = 0;
472         struct acpi_device      *device = NULL;
473
474         ACPI_FUNCTION_TRACE("acpi_bus_notify");
475
476         if (acpi_bus_get_device(handle, &device))
477                 return_VOID;
478
479         switch (type) {
480
481         case ACPI_NOTIFY_BUS_CHECK:
482                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received BUS CHECK notification for device [%s]\n", 
483                         device->pnp.bus_id));
484                 result = acpi_bus_check_scope(device);
485                 /* 
486                  * TBD: We'll need to outsource certain events to non-ACPI
487                  *      drivers via the device manager (device.c).
488                  */
489                 break;
490
491         case ACPI_NOTIFY_DEVICE_CHECK:
492                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE CHECK notification for device [%s]\n", 
493                         device->pnp.bus_id));
494                 result = acpi_bus_check_device(device, NULL);
495                 /* 
496                  * TBD: We'll need to outsource certain events to non-ACPI
497                  *      drivers via the device manager (device.c).
498                  */
499                 break;
500
501         case ACPI_NOTIFY_DEVICE_WAKE:
502                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE WAKE notification for device [%s]\n", 
503                         device->pnp.bus_id));
504                 /* TBD */
505                 break;
506
507         case ACPI_NOTIFY_EJECT_REQUEST:
508                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received EJECT REQUEST notification for device [%s]\n", 
509                         device->pnp.bus_id));
510                 /* TBD */
511                 break;
512
513         case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
514                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received DEVICE CHECK LIGHT notification for device [%s]\n", 
515                         device->pnp.bus_id));
516                 /* TBD: Exactly what does 'light' mean? */
517                 break;
518
519         case ACPI_NOTIFY_FREQUENCY_MISMATCH:
520                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received FREQUENCY MISMATCH notification for device [%s]\n", 
521                         device->pnp.bus_id));
522                 /* TBD */
523                 break;
524
525         case ACPI_NOTIFY_BUS_MODE_MISMATCH:
526                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received BUS MODE MISMATCH notification for device [%s]\n", 
527                         device->pnp.bus_id));
528                 /* TBD */
529                 break;
530
531         case ACPI_NOTIFY_POWER_FAULT:
532                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received POWER FAULT notification for device [%s]\n", 
533                         device->pnp.bus_id));
534                 /* TBD */
535                 break;
536
537         default:
538                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received unknown/unsupported notification [%08x]\n", 
539                         type));
540                 break;
541         }
542
543         return_VOID;
544 }
545
546 /* --------------------------------------------------------------------------
547                              Initialization/Cleanup
548    -------------------------------------------------------------------------- */
549
550 static int __init
551 acpi_bus_init_irq (void)
552 {
553         acpi_status             status = AE_OK;
554         union acpi_object       arg = {ACPI_TYPE_INTEGER};
555         struct acpi_object_list arg_list = {1, &arg};
556         char                    *message = NULL;
557
558         ACPI_FUNCTION_TRACE("acpi_bus_init_irq");
559
560         /* 
561          * Let the system know what interrupt model we are using by
562          * evaluating the \_PIC object, if exists.
563          */
564
565         switch (acpi_irq_model) {
566         case ACPI_IRQ_MODEL_PIC:
567                 message = "PIC";
568                 break;
569         case ACPI_IRQ_MODEL_IOAPIC:
570                 message = "IOAPIC";
571                 break;
572         case ACPI_IRQ_MODEL_IOSAPIC:
573                 message = "IOSAPIC";
574                 break;
575         default:
576                 printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n");
577                 return_VALUE(-ENODEV);
578         }
579
580         printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message);
581
582         arg.integer.value = acpi_irq_model;
583
584         status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL);
585         if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
586                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PIC\n"));
587                 return_VALUE(-ENODEV);
588         }
589
590         return_VALUE(0);
591 }
592
593 void
594 acpi_machine_reset(void)
595 {
596         acpi_status status;
597         FADT_DESCRIPTOR *f = &acpi_fadt;
598
599         if (f->reset_register.register_bit_width != 8) {
600                 printk(KERN_WARNING PREFIX "invalid reset register bit width: 0x%x\n", f->reset_register.register_bit_width);
601                 return_VOID;
602         }
603
604         if (f->reset_register.register_bit_offset != 0) {
605                 printk(KERN_WARNING PREFIX "invalid reset register bit offset: 0x%x\n", f->reset_register.register_bit_offset);
606                 return_VOID;
607         }
608
609         if ((f->reset_register.address_space_id != ACPI_ADR_SPACE_SYSTEM_IO) &&
610                 (f->reset_register.address_space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
611                 (f->reset_register.address_space_id != ACPI_ADR_SPACE_PCI_CONFIG)) {
612                 printk(KERN_WARNING PREFIX "invalid reset register address space id: 0x%x\n", f->reset_register.address_space_id);
613                 return_VOID;
614         }
615
616         status = acpi_hw_low_level_write(f->reset_register.register_bit_width, f->reset_value, &f->reset_register);
617
618         if (status != AE_OK)
619                 printk(KERN_WARNING "ACPI system reset failed 0x%x\n", status);
620 }
621
622 void __init
623 acpi_early_init (void)
624 {
625         acpi_status             status = AE_OK;
626         struct acpi_buffer      buffer = {sizeof(acpi_fadt), &acpi_fadt};
627
628         ACPI_FUNCTION_TRACE("acpi_early_init");
629
630         if (acpi_disabled)
631                 return;
632
633         /* enable workarounds, unless strict ACPI spec. compliance */
634         if (!acpi_strict)
635                 acpi_gbl_enable_interpreter_slack = TRUE;
636
637         status = acpi_initialize_subsystem();
638         if (ACPI_FAILURE(status)) {
639                 printk(KERN_ERR PREFIX "Unable to initialize the ACPI Interpreter\n");
640                 goto error0;
641         }
642
643         status = acpi_load_tables();
644         if (ACPI_FAILURE(status)) {
645                 printk(KERN_ERR PREFIX "Unable to load the System Description Tables\n");
646                 goto error0;
647         }
648
649         /*
650          * Get a separate copy of the FADT for use by other drivers.
651          */
652         status = acpi_get_table(ACPI_TABLE_FADT, 1, &buffer);
653         if (ACPI_FAILURE(status)) {
654                 printk(KERN_ERR PREFIX "Unable to get the FADT\n");
655                 goto error0;
656         }
657
658 #if defined(CONFIG_X86_64)
659         /*
660          * Set up system reset via ACPI if defined in FADT.
661          */
662         if (acpi_fadt.revision >= 2) {
663                 if (acpi_fadt.reset_reg_sup) {
664                         printk(KERN_INFO PREFIX "System reset via FADT Reset Register is supported\n");
665                         /* if no 8042 KBD controller exists, use ACPI reset */
666                         if (!(acpi_fadt.iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER)) {
667                                 machine_reset = acpi_machine_reset;
668                                 if (!reboot_override)
669                                         reboot_type = BOOT_ACPI;
670                         }
671                 }
672         }
673 #endif
674
675 #ifdef CONFIG_X86
676         if (!acpi_ioapic) {
677                 extern acpi_interrupt_flags acpi_sci_flags;
678
679                 /* compatible (0) means level (3) */
680                 if (acpi_sci_flags.trigger == 0)
681                         acpi_sci_flags.trigger = 3;
682
683                 /* Set PIC-mode SCI trigger type */
684                 acpi_pic_sci_set_trigger(acpi_fadt.sci_int, acpi_sci_flags.trigger);
685         } else {
686                 extern int acpi_sci_override_gsi;
687                 /*
688                  * now that acpi_fadt is initialized,
689                  * update it with result from INT_SRC_OVR parsing
690                  */
691                 acpi_fadt.sci_int = acpi_sci_override_gsi;
692         }
693 #endif
694
695         status = acpi_enable_subsystem(~(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE));
696         if (ACPI_FAILURE(status)) {
697                 printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
698                 goto error0;
699         }
700
701         return;
702
703 error0:
704         disable_acpi();
705         return;
706 }
707
708 static int __init
709 acpi_bus_init (void)
710 {
711         int                     result = 0;
712         acpi_status             status = AE_OK;
713         extern acpi_status      acpi_os_initialize1(void);
714
715         ACPI_FUNCTION_TRACE("acpi_bus_init");
716
717         status = acpi_os_initialize1();
718
719         status = acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE);
720         if (ACPI_FAILURE(status)) {
721                 printk(KERN_ERR PREFIX "Unable to start the ACPI Interpreter\n");
722                 goto error1;
723         }
724
725         if (ACPI_FAILURE(status)) {
726                 printk(KERN_ERR PREFIX "Unable to initialize ACPI OS objects\n");
727                 goto error1;
728         }
729 #ifdef CONFIG_ACPI_EC
730         /*
731          * ACPI 2.0 requires the EC driver to be loaded and work before
732          * the EC device is found in the namespace (i.e. before acpi_initialize_objects()
733          * is called).
734          *
735          * This is accomplished by looking for the ECDT table, and getting 
736          * the EC parameters out of that.
737          */
738         status = acpi_ec_ecdt_probe();
739         /* Ignore result. Not having an ECDT is not fatal. */
740 #endif
741
742         status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
743         if (ACPI_FAILURE(status)) {
744                 printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
745                 goto error1;
746         }
747
748         printk(KERN_INFO PREFIX "Interpreter enabled\n");
749
750         /*
751          * Get the system interrupt model and evaluate \_PIC.
752          */
753         result = acpi_bus_init_irq();
754         if (result)
755                 goto error1;
756
757         /*
758          * Register the for all standard device notifications.
759          */
760         status = acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, &acpi_bus_notify, NULL);
761         if (ACPI_FAILURE(status)) {
762                 printk(KERN_ERR PREFIX "Unable to register for device notifications\n");
763                 goto error1;
764         }
765
766         /*
767          * Create the top ACPI proc directory
768          */
769         acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
770
771         return_VALUE(0);
772
773         /* Mimic structured exception handling */
774 error1:
775         acpi_terminate();
776         return_VALUE(-ENODEV);
777 }
778
779 decl_subsys(acpi,NULL,NULL);
780
781 static int __init acpi_init (void)
782 {
783         int                     result = 0;
784
785         ACPI_FUNCTION_TRACE("acpi_init");
786
787         printk(KERN_INFO PREFIX "Subsystem revision %08x\n",
788                 ACPI_CA_VERSION);
789
790         if (acpi_disabled) {
791                 printk(KERN_INFO PREFIX "Interpreter disabled.\n");
792                 return -ENODEV;
793         }
794
795         firmware_register(&acpi_subsys);
796
797         result = acpi_bus_init();
798
799         if (!result) {
800 #ifdef CONFIG_PM
801                 if (!PM_IS_ACTIVE())
802                         pm_active = 1;
803                 else {
804                         printk(KERN_INFO PREFIX "APM is already active, exiting\n");
805                         disable_acpi();
806                         result = -ENODEV;
807                 }
808 #endif
809         } else
810                 disable_acpi();
811
812         return_VALUE(result);
813 }
814
815 subsys_initcall(acpi_init);