Merge ../linux-2.6-watchdog-mm
[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         case ACPI_IRQ_MODEL_PLATFORM:
565                 message = "platform specific model";
566                 break;
567         default:
568                 printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n");
569                 return -ENODEV;
570         }
571
572         printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message);
573
574         arg.integer.value = acpi_irq_model;
575
576         status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL);
577         if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
578                 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC"));
579                 return -ENODEV;
580         }
581
582         return 0;
583 }
584
585 void __init acpi_early_init(void)
586 {
587         acpi_status status = AE_OK;
588         struct acpi_buffer buffer = { sizeof(acpi_fadt), &acpi_fadt };
589
590
591         if (acpi_disabled)
592                 return;
593
594         printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
595
596         /* enable workarounds, unless strict ACPI spec. compliance */
597         if (!acpi_strict)
598                 acpi_gbl_enable_interpreter_slack = TRUE;
599
600         status = acpi_initialize_subsystem();
601         if (ACPI_FAILURE(status)) {
602                 printk(KERN_ERR PREFIX
603                        "Unable to initialize the ACPI Interpreter\n");
604                 goto error0;
605         }
606
607         status = acpi_load_tables();
608         if (ACPI_FAILURE(status)) {
609                 printk(KERN_ERR PREFIX
610                        "Unable to load the System Description Tables\n");
611                 goto error0;
612         }
613
614         /*
615          * Get a separate copy of the FADT for use by other drivers.
616          */
617         status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &buffer);
618         if (ACPI_FAILURE(status)) {
619                 printk(KERN_ERR PREFIX "Unable to get the FADT\n");
620                 goto error0;
621         }
622 #ifdef CONFIG_X86
623         if (!acpi_ioapic) {
624                 extern acpi_interrupt_flags acpi_sci_flags;
625
626                 /* compatible (0) means level (3) */
627                 if (acpi_sci_flags.trigger == 0)
628                         acpi_sci_flags.trigger = 3;
629
630                 /* Set PIC-mode SCI trigger type */
631                 acpi_pic_sci_set_trigger(acpi_fadt.sci_int,
632                                          acpi_sci_flags.trigger);
633         } else {
634                 extern int acpi_sci_override_gsi;
635                 /*
636                  * now that acpi_fadt is initialized,
637                  * update it with result from INT_SRC_OVR parsing
638                  */
639                 acpi_fadt.sci_int = acpi_sci_override_gsi;
640         }
641 #endif
642
643         status =
644             acpi_enable_subsystem(~
645                                   (ACPI_NO_HARDWARE_INIT |
646                                    ACPI_NO_ACPI_ENABLE));
647         if (ACPI_FAILURE(status)) {
648                 printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
649                 goto error0;
650         }
651
652         return;
653
654       error0:
655         disable_acpi();
656         return;
657 }
658
659 static int __init acpi_bus_init(void)
660 {
661         int result = 0;
662         acpi_status status = AE_OK;
663         extern acpi_status acpi_os_initialize1(void);
664
665
666         status = acpi_os_initialize1();
667
668         status =
669             acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE);
670         if (ACPI_FAILURE(status)) {
671                 printk(KERN_ERR PREFIX
672                        "Unable to start the ACPI Interpreter\n");
673                 goto error1;
674         }
675
676         if (ACPI_FAILURE(status)) {
677                 printk(KERN_ERR PREFIX
678                        "Unable to initialize ACPI OS objects\n");
679                 goto error1;
680         }
681 #ifdef CONFIG_ACPI_EC
682         /*
683          * ACPI 2.0 requires the EC driver to be loaded and work before
684          * the EC device is found in the namespace (i.e. before acpi_initialize_objects()
685          * is called).
686          *
687          * This is accomplished by looking for the ECDT table, and getting 
688          * the EC parameters out of that.
689          */
690         status = acpi_ec_ecdt_probe();
691         /* Ignore result. Not having an ECDT is not fatal. */
692 #endif
693
694         status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
695         if (ACPI_FAILURE(status)) {
696                 printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
697                 goto error1;
698         }
699
700         printk(KERN_INFO PREFIX "Interpreter enabled\n");
701
702         /*
703          * Get the system interrupt model and evaluate \_PIC.
704          */
705         result = acpi_bus_init_irq();
706         if (result)
707                 goto error1;
708
709         /*
710          * Register the for all standard device notifications.
711          */
712         status =
713             acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
714                                         &acpi_bus_notify, NULL);
715         if (ACPI_FAILURE(status)) {
716                 printk(KERN_ERR PREFIX
717                        "Unable to register for device notifications\n");
718                 goto error1;
719         }
720
721         /*
722          * Create the top ACPI proc directory
723          */
724         acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
725
726         return 0;
727
728         /* Mimic structured exception handling */
729       error1:
730         acpi_terminate();
731         return -ENODEV;
732 }
733
734 decl_subsys(acpi, NULL, NULL);
735
736 static int __init acpi_init(void)
737 {
738         int result = 0;
739
740
741         if (acpi_disabled) {
742                 printk(KERN_INFO PREFIX "Interpreter disabled.\n");
743                 return -ENODEV;
744         }
745
746         result = firmware_register(&acpi_subsys);
747         if (result < 0)
748                 printk(KERN_WARNING "%s: firmware_register error: %d\n",
749                         __FUNCTION__, result);
750
751         result = acpi_bus_init();
752
753         if (!result) {
754 #ifdef CONFIG_PM_LEGACY
755                 if (!PM_IS_ACTIVE())
756                         pm_active = 1;
757                 else {
758                         printk(KERN_INFO PREFIX
759                                "APM is already active, exiting\n");
760                         disable_acpi();
761                         result = -ENODEV;
762                 }
763 #endif
764         } else
765                 disable_acpi();
766
767         return result;
768 }
769
770 subsys_initcall(acpi_init);