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