1 /* 2 * acpi_power.c - ACPI Bus Power Management ($Revision: 39 $) 3 * 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 6 * 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or (at 12 * your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 22 * 23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24 */ 25 26 /* 27 * ACPI power-managed devices may be controlled in two ways: 28 * 1. via "Device Specific (D-State) Control" 29 * 2. via "Power Resource Control". 30 * This module is used to manage devices relying on Power Resource Control. 31 * 32 * An ACPI "power resource object" describes a software controllable power 33 * plane, clock plane, or other resource used by a power managed device. 34 * A device may rely on multiple power resources, and a power resource 35 * may be shared by multiple devices. 36 */ 37 38 #include <linux/kernel.h> 39 #include <linux/module.h> 40 #include <linux/init.h> 41 #include <linux/types.h> 42 #include <linux/slab.h> 43 #include <linux/pm_runtime.h> 44 #include <linux/sysfs.h> 45 #include <acpi/acpi_bus.h> 46 #include <acpi/acpi_drivers.h> 47 #include "sleep.h" 48 #include "internal.h" 49 50 #define PREFIX "ACPI: " 51 52 #define _COMPONENT ACPI_POWER_COMPONENT 53 ACPI_MODULE_NAME("power"); 54 #define ACPI_POWER_CLASS "power_resource" 55 #define ACPI_POWER_DEVICE_NAME "Power Resource" 56 #define ACPI_POWER_FILE_INFO "info" 57 #define ACPI_POWER_FILE_STATUS "state" 58 #define ACPI_POWER_RESOURCE_STATE_OFF 0x00 59 #define ACPI_POWER_RESOURCE_STATE_ON 0x01 60 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF 61 62 struct acpi_power_resource { 63 struct acpi_device device; 64 struct list_head list_node; 65 char *name; 66 u32 system_level; 67 u32 order; 68 unsigned int ref_count; 69 bool wakeup_enabled; 70 struct mutex resource_lock; 71 }; 72 73 struct acpi_power_resource_entry { 74 struct list_head node; 75 struct acpi_power_resource *resource; 76 }; 77 78 static LIST_HEAD(acpi_power_resource_list); 79 static DEFINE_MUTEX(power_resource_list_lock); 80 81 /* -------------------------------------------------------------------------- 82 Power Resource Management 83 -------------------------------------------------------------------------- */ 84 85 static inline 86 struct acpi_power_resource *to_power_resource(struct acpi_device *device) 87 { 88 return container_of(device, struct acpi_power_resource, device); 89 } 90 91 static struct acpi_power_resource *acpi_power_get_context(acpi_handle handle) 92 { 93 struct acpi_device *device; 94 95 if (acpi_bus_get_device(handle, &device)) 96 return NULL; 97 98 return to_power_resource(device); 99 } 100 101 static int acpi_power_resources_list_add(acpi_handle handle, 102 struct list_head *list) 103 { 104 struct acpi_power_resource *resource = acpi_power_get_context(handle); 105 struct acpi_power_resource_entry *entry; 106 107 if (!resource || !list) 108 return -EINVAL; 109 110 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 111 if (!entry) 112 return -ENOMEM; 113 114 entry->resource = resource; 115 if (!list_empty(list)) { 116 struct acpi_power_resource_entry *e; 117 118 list_for_each_entry(e, list, node) 119 if (e->resource->order > resource->order) { 120 list_add_tail(&entry->node, &e->node); 121 return 0; 122 } 123 } 124 list_add_tail(&entry->node, list); 125 return 0; 126 } 127 128 void acpi_power_resources_list_free(struct list_head *list) 129 { 130 struct acpi_power_resource_entry *entry, *e; 131 132 list_for_each_entry_safe(entry, e, list, node) { 133 list_del(&entry->node); 134 kfree(entry); 135 } 136 } 137 138 int acpi_extract_power_resources(union acpi_object *package, unsigned int start, 139 struct list_head *list) 140 { 141 unsigned int i; 142 int err = 0; 143 144 for (i = start; i < package->package.count; i++) { 145 union acpi_object *element = &package->package.elements[i]; 146 acpi_handle rhandle; 147 148 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) { 149 err = -ENODATA; 150 break; 151 } 152 rhandle = element->reference.handle; 153 if (!rhandle) { 154 err = -ENODEV; 155 break; 156 } 157 err = acpi_add_power_resource(rhandle); 158 if (err) 159 break; 160 161 err = acpi_power_resources_list_add(rhandle, list); 162 if (err) 163 break; 164 } 165 if (err) 166 acpi_power_resources_list_free(list); 167 168 return err; 169 } 170 171 static int acpi_power_get_state(acpi_handle handle, int *state) 172 { 173 acpi_status status = AE_OK; 174 unsigned long long sta = 0; 175 char node_name[5]; 176 struct acpi_buffer buffer = { sizeof(node_name), node_name }; 177 178 179 if (!handle || !state) 180 return -EINVAL; 181 182 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); 183 if (ACPI_FAILURE(status)) 184 return -ENODEV; 185 186 *state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON: 187 ACPI_POWER_RESOURCE_STATE_OFF; 188 189 acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); 190 191 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", 192 node_name, 193 *state ? "on" : "off")); 194 195 return 0; 196 } 197 198 static int acpi_power_get_list_state(struct list_head *list, int *state) 199 { 200 struct acpi_power_resource_entry *entry; 201 int cur_state; 202 203 if (!list || !state) 204 return -EINVAL; 205 206 /* The state of the list is 'on' IFF all resources are 'on'. */ 207 list_for_each_entry(entry, list, node) { 208 struct acpi_power_resource *resource = entry->resource; 209 acpi_handle handle = resource->device.handle; 210 int result; 211 212 mutex_lock(&resource->resource_lock); 213 result = acpi_power_get_state(handle, &cur_state); 214 mutex_unlock(&resource->resource_lock); 215 if (result) 216 return result; 217 218 if (cur_state != ACPI_POWER_RESOURCE_STATE_ON) 219 break; 220 } 221 222 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n", 223 cur_state ? "on" : "off")); 224 225 *state = cur_state; 226 return 0; 227 } 228 229 static int __acpi_power_on(struct acpi_power_resource *resource) 230 { 231 acpi_status status = AE_OK; 232 233 status = acpi_evaluate_object(resource->device.handle, "_ON", NULL, NULL); 234 if (ACPI_FAILURE(status)) 235 return -ENODEV; 236 237 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", 238 resource->name)); 239 240 return 0; 241 } 242 243 static int acpi_power_on_unlocked(struct acpi_power_resource *resource) 244 { 245 int result = 0; 246 247 if (resource->ref_count++) { 248 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 249 "Power resource [%s] already on\n", 250 resource->name)); 251 } else { 252 result = __acpi_power_on(resource); 253 if (result) 254 resource->ref_count--; 255 } 256 return result; 257 } 258 259 static int acpi_power_on(struct acpi_power_resource *resource) 260 { 261 int result; 262 263 mutex_lock(&resource->resource_lock); 264 result = acpi_power_on_unlocked(resource); 265 mutex_unlock(&resource->resource_lock); 266 return result; 267 } 268 269 static int __acpi_power_off(struct acpi_power_resource *resource) 270 { 271 acpi_status status; 272 273 status = acpi_evaluate_object(resource->device.handle, "_OFF", 274 NULL, NULL); 275 if (ACPI_FAILURE(status)) 276 return -ENODEV; 277 278 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned off\n", 279 resource->name)); 280 return 0; 281 } 282 283 static int acpi_power_off_unlocked(struct acpi_power_resource *resource) 284 { 285 int result = 0; 286 287 if (!resource->ref_count) { 288 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 289 "Power resource [%s] already off\n", 290 resource->name)); 291 return 0; 292 } 293 294 if (--resource->ref_count) { 295 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 296 "Power resource [%s] still in use\n", 297 resource->name)); 298 } else { 299 result = __acpi_power_off(resource); 300 if (result) 301 resource->ref_count++; 302 } 303 return result; 304 } 305 306 static int acpi_power_off(struct acpi_power_resource *resource) 307 { 308 int result; 309 310 mutex_lock(&resource->resource_lock); 311 result = acpi_power_off_unlocked(resource); 312 mutex_unlock(&resource->resource_lock); 313 return result; 314 } 315 316 static int acpi_power_off_list(struct list_head *list) 317 { 318 struct acpi_power_resource_entry *entry; 319 int result = 0; 320 321 list_for_each_entry_reverse(entry, list, node) { 322 result = acpi_power_off(entry->resource); 323 if (result) 324 goto err; 325 } 326 return 0; 327 328 err: 329 list_for_each_entry_continue(entry, list, node) 330 acpi_power_on(entry->resource); 331 332 return result; 333 } 334 335 static int acpi_power_on_list(struct list_head *list) 336 { 337 struct acpi_power_resource_entry *entry; 338 int result = 0; 339 340 list_for_each_entry(entry, list, node) { 341 result = acpi_power_on(entry->resource); 342 if (result) 343 goto err; 344 } 345 return 0; 346 347 err: 348 list_for_each_entry_continue_reverse(entry, list, node) 349 acpi_power_off(entry->resource); 350 351 return result; 352 } 353 354 static struct attribute *attrs[] = { 355 NULL, 356 }; 357 358 static struct attribute_group attr_groups[] = { 359 [ACPI_STATE_D0] = { 360 .name = "power_resources_D0", 361 .attrs = attrs, 362 }, 363 [ACPI_STATE_D1] = { 364 .name = "power_resources_D1", 365 .attrs = attrs, 366 }, 367 [ACPI_STATE_D2] = { 368 .name = "power_resources_D2", 369 .attrs = attrs, 370 }, 371 [ACPI_STATE_D3_HOT] = { 372 .name = "power_resources_D3hot", 373 .attrs = attrs, 374 }, 375 }; 376 377 static struct attribute_group wakeup_attr_group = { 378 .name = "power_resources_wakeup", 379 .attrs = attrs, 380 }; 381 382 static void acpi_power_hide_list(struct acpi_device *adev, 383 struct list_head *resources, 384 struct attribute_group *attr_group) 385 { 386 struct acpi_power_resource_entry *entry; 387 388 if (list_empty(resources)) 389 return; 390 391 list_for_each_entry_reverse(entry, resources, node) { 392 struct acpi_device *res_dev = &entry->resource->device; 393 394 sysfs_remove_link_from_group(&adev->dev.kobj, 395 attr_group->name, 396 dev_name(&res_dev->dev)); 397 } 398 sysfs_remove_group(&adev->dev.kobj, attr_group); 399 } 400 401 static void acpi_power_expose_list(struct acpi_device *adev, 402 struct list_head *resources, 403 struct attribute_group *attr_group) 404 { 405 struct acpi_power_resource_entry *entry; 406 int ret; 407 408 if (list_empty(resources)) 409 return; 410 411 ret = sysfs_create_group(&adev->dev.kobj, attr_group); 412 if (ret) 413 return; 414 415 list_for_each_entry(entry, resources, node) { 416 struct acpi_device *res_dev = &entry->resource->device; 417 418 ret = sysfs_add_link_to_group(&adev->dev.kobj, 419 attr_group->name, 420 &res_dev->dev.kobj, 421 dev_name(&res_dev->dev)); 422 if (ret) { 423 acpi_power_hide_list(adev, resources, attr_group); 424 break; 425 } 426 } 427 } 428 429 static void acpi_power_expose_hide(struct acpi_device *adev, 430 struct list_head *resources, 431 struct attribute_group *attr_group, 432 bool expose) 433 { 434 if (expose) 435 acpi_power_expose_list(adev, resources, attr_group); 436 else 437 acpi_power_hide_list(adev, resources, attr_group); 438 } 439 440 void acpi_power_add_remove_device(struct acpi_device *adev, bool add) 441 { 442 int state; 443 444 if (adev->wakeup.flags.valid) 445 acpi_power_expose_hide(adev, &adev->wakeup.resources, 446 &wakeup_attr_group, add); 447 448 if (!adev->power.flags.power_resources) 449 return; 450 451 for (state = ACPI_STATE_D0; state <= ACPI_STATE_D3_HOT; state++) 452 acpi_power_expose_hide(adev, 453 &adev->power.states[state].resources, 454 &attr_groups[state], add); 455 } 456 457 int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p) 458 { 459 struct acpi_power_resource_entry *entry; 460 int system_level = 5; 461 462 list_for_each_entry(entry, list, node) { 463 struct acpi_power_resource *resource = entry->resource; 464 acpi_handle handle = resource->device.handle; 465 int result; 466 int state; 467 468 mutex_lock(&resource->resource_lock); 469 470 result = acpi_power_get_state(handle, &state); 471 if (result) { 472 mutex_unlock(&resource->resource_lock); 473 return result; 474 } 475 if (state == ACPI_POWER_RESOURCE_STATE_ON) { 476 resource->ref_count++; 477 resource->wakeup_enabled = true; 478 } 479 if (system_level > resource->system_level) 480 system_level = resource->system_level; 481 482 mutex_unlock(&resource->resource_lock); 483 } 484 *system_level_p = system_level; 485 return 0; 486 } 487 488 /* -------------------------------------------------------------------------- 489 Device Power Management 490 -------------------------------------------------------------------------- */ 491 492 /** 493 * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in 494 * ACPI 3.0) _PSW (Power State Wake) 495 * @dev: Device to handle. 496 * @enable: 0 - disable, 1 - enable the wake capabilities of the device. 497 * @sleep_state: Target sleep state of the system. 498 * @dev_state: Target power state of the device. 499 * 500 * Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power 501 * State Wake) for the device, if present. On failure reset the device's 502 * wakeup.flags.valid flag. 503 * 504 * RETURN VALUE: 505 * 0 if either _DSW or _PSW has been successfully executed 506 * 0 if neither _DSW nor _PSW has been found 507 * -ENODEV if the execution of either _DSW or _PSW has failed 508 */ 509 int acpi_device_sleep_wake(struct acpi_device *dev, 510 int enable, int sleep_state, int dev_state) 511 { 512 union acpi_object in_arg[3]; 513 struct acpi_object_list arg_list = { 3, in_arg }; 514 acpi_status status = AE_OK; 515 516 /* 517 * Try to execute _DSW first. 518 * 519 * Three agruments are needed for the _DSW object: 520 * Argument 0: enable/disable the wake capabilities 521 * Argument 1: target system state 522 * Argument 2: target device state 523 * When _DSW object is called to disable the wake capabilities, maybe 524 * the first argument is filled. The values of the other two agruments 525 * are meaningless. 526 */ 527 in_arg[0].type = ACPI_TYPE_INTEGER; 528 in_arg[0].integer.value = enable; 529 in_arg[1].type = ACPI_TYPE_INTEGER; 530 in_arg[1].integer.value = sleep_state; 531 in_arg[2].type = ACPI_TYPE_INTEGER; 532 in_arg[2].integer.value = dev_state; 533 status = acpi_evaluate_object(dev->handle, "_DSW", &arg_list, NULL); 534 if (ACPI_SUCCESS(status)) { 535 return 0; 536 } else if (status != AE_NOT_FOUND) { 537 printk(KERN_ERR PREFIX "_DSW execution failed\n"); 538 dev->wakeup.flags.valid = 0; 539 return -ENODEV; 540 } 541 542 /* Execute _PSW */ 543 status = acpi_execute_simple_method(dev->handle, "_PSW", enable); 544 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { 545 printk(KERN_ERR PREFIX "_PSW execution failed\n"); 546 dev->wakeup.flags.valid = 0; 547 return -ENODEV; 548 } 549 550 return 0; 551 } 552 553 /* 554 * Prepare a wakeup device, two steps (Ref ACPI 2.0:P229): 555 * 1. Power on the power resources required for the wakeup device 556 * 2. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power 557 * State Wake) for the device, if present 558 */ 559 int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) 560 { 561 struct acpi_power_resource_entry *entry; 562 int err = 0; 563 564 if (!dev || !dev->wakeup.flags.valid) 565 return -EINVAL; 566 567 mutex_lock(&acpi_device_lock); 568 569 if (dev->wakeup.prepare_count++) 570 goto out; 571 572 list_for_each_entry(entry, &dev->wakeup.resources, node) { 573 struct acpi_power_resource *resource = entry->resource; 574 575 mutex_lock(&resource->resource_lock); 576 577 if (!resource->wakeup_enabled) { 578 err = acpi_power_on_unlocked(resource); 579 if (!err) 580 resource->wakeup_enabled = true; 581 } 582 583 mutex_unlock(&resource->resource_lock); 584 585 if (err) { 586 dev_err(&dev->dev, 587 "Cannot turn wakeup power resources on\n"); 588 dev->wakeup.flags.valid = 0; 589 goto out; 590 } 591 } 592 /* 593 * Passing 3 as the third argument below means the device may be 594 * put into arbitrary power state afterward. 595 */ 596 err = acpi_device_sleep_wake(dev, 1, sleep_state, 3); 597 if (err) 598 dev->wakeup.prepare_count = 0; 599 600 out: 601 mutex_unlock(&acpi_device_lock); 602 return err; 603 } 604 605 /* 606 * Shutdown a wakeup device, counterpart of above method 607 * 1. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power 608 * State Wake) for the device, if present 609 * 2. Shutdown down the power resources 610 */ 611 int acpi_disable_wakeup_device_power(struct acpi_device *dev) 612 { 613 struct acpi_power_resource_entry *entry; 614 int err = 0; 615 616 if (!dev || !dev->wakeup.flags.valid) 617 return -EINVAL; 618 619 mutex_lock(&acpi_device_lock); 620 621 if (--dev->wakeup.prepare_count > 0) 622 goto out; 623 624 /* 625 * Executing the code below even if prepare_count is already zero when 626 * the function is called may be useful, for example for initialisation. 627 */ 628 if (dev->wakeup.prepare_count < 0) 629 dev->wakeup.prepare_count = 0; 630 631 err = acpi_device_sleep_wake(dev, 0, 0, 0); 632 if (err) 633 goto out; 634 635 list_for_each_entry(entry, &dev->wakeup.resources, node) { 636 struct acpi_power_resource *resource = entry->resource; 637 638 mutex_lock(&resource->resource_lock); 639 640 if (resource->wakeup_enabled) { 641 err = acpi_power_off_unlocked(resource); 642 if (!err) 643 resource->wakeup_enabled = false; 644 } 645 646 mutex_unlock(&resource->resource_lock); 647 648 if (err) { 649 dev_err(&dev->dev, 650 "Cannot turn wakeup power resources off\n"); 651 dev->wakeup.flags.valid = 0; 652 break; 653 } 654 } 655 656 out: 657 mutex_unlock(&acpi_device_lock); 658 return err; 659 } 660 661 int acpi_power_get_inferred_state(struct acpi_device *device, int *state) 662 { 663 int result = 0; 664 int list_state = 0; 665 int i = 0; 666 667 if (!device || !state) 668 return -EINVAL; 669 670 /* 671 * We know a device's inferred power state when all the resources 672 * required for a given D-state are 'on'. 673 */ 674 for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { 675 struct list_head *list = &device->power.states[i].resources; 676 677 if (list_empty(list)) 678 continue; 679 680 result = acpi_power_get_list_state(list, &list_state); 681 if (result) 682 return result; 683 684 if (list_state == ACPI_POWER_RESOURCE_STATE_ON) { 685 *state = i; 686 return 0; 687 } 688 } 689 690 *state = ACPI_STATE_D3_COLD; 691 return 0; 692 } 693 694 int acpi_power_on_resources(struct acpi_device *device, int state) 695 { 696 if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3_HOT) 697 return -EINVAL; 698 699 return acpi_power_on_list(&device->power.states[state].resources); 700 } 701 702 int acpi_power_transition(struct acpi_device *device, int state) 703 { 704 int result = 0; 705 706 if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) 707 return -EINVAL; 708 709 if (device->power.state == state || !device->flags.power_manageable) 710 return 0; 711 712 if ((device->power.state < ACPI_STATE_D0) 713 || (device->power.state > ACPI_STATE_D3_COLD)) 714 return -ENODEV; 715 716 /* TBD: Resources must be ordered. */ 717 718 /* 719 * First we reference all power resources required in the target list 720 * (e.g. so the device doesn't lose power while transitioning). Then, 721 * we dereference all power resources used in the current list. 722 */ 723 if (state < ACPI_STATE_D3_COLD) 724 result = acpi_power_on_list( 725 &device->power.states[state].resources); 726 727 if (!result && device->power.state < ACPI_STATE_D3_COLD) 728 acpi_power_off_list( 729 &device->power.states[device->power.state].resources); 730 731 /* We shouldn't change the state unless the above operations succeed. */ 732 device->power.state = result ? ACPI_STATE_UNKNOWN : state; 733 734 return result; 735 } 736 737 static void acpi_release_power_resource(struct device *dev) 738 { 739 struct acpi_device *device = to_acpi_device(dev); 740 struct acpi_power_resource *resource; 741 742 resource = container_of(device, struct acpi_power_resource, device); 743 744 mutex_lock(&power_resource_list_lock); 745 list_del(&resource->list_node); 746 mutex_unlock(&power_resource_list_lock); 747 748 acpi_free_pnp_ids(&device->pnp); 749 kfree(resource); 750 } 751 752 static ssize_t acpi_power_in_use_show(struct device *dev, 753 struct device_attribute *attr, 754 char *buf) { 755 struct acpi_power_resource *resource; 756 757 resource = to_power_resource(to_acpi_device(dev)); 758 return sprintf(buf, "%u\n", !!resource->ref_count); 759 } 760 static DEVICE_ATTR(resource_in_use, 0444, acpi_power_in_use_show, NULL); 761 762 static void acpi_power_sysfs_remove(struct acpi_device *device) 763 { 764 device_remove_file(&device->dev, &dev_attr_resource_in_use); 765 } 766 767 int acpi_add_power_resource(acpi_handle handle) 768 { 769 struct acpi_power_resource *resource; 770 struct acpi_device *device = NULL; 771 union acpi_object acpi_object; 772 struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object }; 773 acpi_status status; 774 int state, result = -ENODEV; 775 776 acpi_bus_get_device(handle, &device); 777 if (device) 778 return 0; 779 780 resource = kzalloc(sizeof(*resource), GFP_KERNEL); 781 if (!resource) 782 return -ENOMEM; 783 784 device = &resource->device; 785 acpi_init_device_object(device, handle, ACPI_BUS_TYPE_POWER, 786 ACPI_STA_DEFAULT); 787 mutex_init(&resource->resource_lock); 788 INIT_LIST_HEAD(&resource->list_node); 789 resource->name = device->pnp.bus_id; 790 strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); 791 strcpy(acpi_device_class(device), ACPI_POWER_CLASS); 792 device->power.state = ACPI_STATE_UNKNOWN; 793 794 /* Evalute the object to get the system level and resource order. */ 795 status = acpi_evaluate_object(handle, NULL, NULL, &buffer); 796 if (ACPI_FAILURE(status)) 797 goto err; 798 799 resource->system_level = acpi_object.power_resource.system_level; 800 resource->order = acpi_object.power_resource.resource_order; 801 802 result = acpi_power_get_state(handle, &state); 803 if (result) 804 goto err; 805 806 printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), 807 acpi_device_bid(device), state ? "on" : "off"); 808 809 device->flags.match_driver = true; 810 result = acpi_device_add(device, acpi_release_power_resource); 811 if (result) 812 goto err; 813 814 if (!device_create_file(&device->dev, &dev_attr_resource_in_use)) 815 device->remove = acpi_power_sysfs_remove; 816 817 mutex_lock(&power_resource_list_lock); 818 list_add(&resource->list_node, &acpi_power_resource_list); 819 mutex_unlock(&power_resource_list_lock); 820 acpi_device_add_finalize(device); 821 return 0; 822 823 err: 824 acpi_release_power_resource(&device->dev); 825 return result; 826 } 827 828 #ifdef CONFIG_ACPI_SLEEP 829 void acpi_resume_power_resources(void) 830 { 831 struct acpi_power_resource *resource; 832 833 mutex_lock(&power_resource_list_lock); 834 835 list_for_each_entry(resource, &acpi_power_resource_list, list_node) { 836 int result, state; 837 838 mutex_lock(&resource->resource_lock); 839 840 result = acpi_power_get_state(resource->device.handle, &state); 841 if (result) { 842 mutex_unlock(&resource->resource_lock); 843 continue; 844 } 845 846 if (state == ACPI_POWER_RESOURCE_STATE_OFF 847 && resource->ref_count) { 848 dev_info(&resource->device.dev, "Turning ON\n"); 849 __acpi_power_on(resource); 850 } else if (state == ACPI_POWER_RESOURCE_STATE_ON 851 && !resource->ref_count) { 852 dev_info(&resource->device.dev, "Turning OFF\n"); 853 __acpi_power_off(resource); 854 } 855 856 mutex_unlock(&resource->resource_lock); 857 } 858 859 mutex_unlock(&power_resource_list_lock); 860 } 861 #endif 862