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