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