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