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