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); 776