linux/drivers/acpi/power.c
<<
>>
Prefs
   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 <acpi/acpi_bus.h>
  45#include <acpi/acpi_drivers.h>
  46#include "sleep.h"
  47#include "internal.h"
  48
  49#define PREFIX "ACPI: "
  50
  51#define _COMPONENT                      ACPI_POWER_COMPONENT
  52ACPI_MODULE_NAME("power");
  53#define ACPI_POWER_CLASS                "power_resource"
  54#define ACPI_POWER_DEVICE_NAME          "Power Resource"
  55#define ACPI_POWER_FILE_INFO            "info"
  56#define ACPI_POWER_FILE_STATUS          "state"
  57#define ACPI_POWER_RESOURCE_STATE_OFF   0x00
  58#define ACPI_POWER_RESOURCE_STATE_ON    0x01
  59#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
  60
  61static int acpi_power_add(struct acpi_device *device);
  62static int acpi_power_remove(struct acpi_device *device, int type);
  63static int acpi_power_resume(struct acpi_device *device);
  64
  65static const struct acpi_device_id power_device_ids[] = {
  66        {ACPI_POWER_HID, 0},
  67        {"", 0},
  68};
  69MODULE_DEVICE_TABLE(acpi, power_device_ids);
  70
  71static struct acpi_driver acpi_power_driver = {
  72        .name = "power",
  73        .class = ACPI_POWER_CLASS,
  74        .ids = power_device_ids,
  75        .ops = {
  76                .add = acpi_power_add,
  77                .remove = acpi_power_remove,
  78                .resume = acpi_power_resume,
  79                },
  80};
  81
  82/*
  83 * A power managed device
  84 * A device may rely on multiple power resources.
  85 * */
  86struct acpi_power_managed_device {
  87        struct device *dev; /* The physical device */
  88        acpi_handle *handle;
  89};
  90
  91struct acpi_power_resource_device {
  92        struct acpi_power_managed_device *device;
  93        struct acpi_power_resource_device *next;
  94};
  95
  96struct acpi_power_resource {
  97        struct acpi_device * device;
  98        acpi_bus_id name;
  99        u32 system_level;
 100        u32 order;
 101        unsigned int ref_count;
 102        struct mutex resource_lock;
 103
 104        /* List of devices relying on this power resource */
 105        struct acpi_power_resource_device *devices;
 106};
 107
 108static struct list_head acpi_power_resource_list;
 109
 110/* --------------------------------------------------------------------------
 111                             Power Resource Management
 112   -------------------------------------------------------------------------- */
 113
 114static int
 115acpi_power_get_context(acpi_handle handle,
 116                       struct acpi_power_resource **resource)
 117{
 118        int result = 0;
 119        struct acpi_device *device = NULL;
 120
 121
 122        if (!resource)
 123                return -ENODEV;
 124
 125        result = acpi_bus_get_device(handle, &device);
 126        if (result) {
 127                printk(KERN_WARNING PREFIX "Getting context [%p]\n", handle);
 128                return result;
 129        }
 130
 131        *resource = acpi_driver_data(device);
 132        if (!*resource)
 133                return -ENODEV;
 134
 135        return 0;
 136}
 137
 138static int acpi_power_get_state(acpi_handle handle, int *state)
 139{
 140        acpi_status status = AE_OK;
 141        unsigned long long sta = 0;
 142        char node_name[5];
 143        struct acpi_buffer buffer = { sizeof(node_name), node_name };
 144
 145
 146        if (!handle || !state)
 147                return -EINVAL;
 148
 149        status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
 150        if (ACPI_FAILURE(status))
 151                return -ENODEV;
 152
 153        *state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON:
 154                              ACPI_POWER_RESOURCE_STATE_OFF;
 155
 156        acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
 157
 158        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
 159                          node_name,
 160                                *state ? "on" : "off"));
 161
 162        return 0;
 163}
 164
 165static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
 166{
 167        int cur_state;
 168        int i = 0;
 169
 170        if (!list || !state)
 171                return -EINVAL;
 172
 173        /* The state of the list is 'on' IFF all resources are 'on'. */
 174
 175        for (i = 0; i < list->count; i++) {
 176                struct acpi_power_resource *resource;
 177                acpi_handle handle = list->handles[i];
 178                int result;
 179
 180                result = acpi_power_get_context(handle, &resource);
 181                if (result)
 182                        return result;
 183
 184                mutex_lock(&resource->resource_lock);
 185
 186                result = acpi_power_get_state(handle, &cur_state);
 187
 188                mutex_unlock(&resource->resource_lock);
 189
 190                if (result)
 191                        return result;
 192
 193                if (cur_state != ACPI_POWER_RESOURCE_STATE_ON)
 194                        break;
 195        }
 196
 197        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n",
 198                          cur_state ? "on" : "off"));
 199
 200        *state = cur_state;
 201
 202        return 0;
 203}
 204
 205/* Resume the device when all power resources in _PR0 are on */
 206static void acpi_power_on_device(struct acpi_power_managed_device *device)
 207{
 208        struct acpi_device *acpi_dev;
 209        acpi_handle handle = device->handle;
 210        int state;
 211
 212        if (acpi_bus_get_device(handle, &acpi_dev))
 213                return;
 214
 215        if(acpi_power_get_inferred_state(acpi_dev, &state))
 216                return;
 217
 218        if (state == ACPI_STATE_D0 && pm_runtime_suspended(device->dev))
 219                pm_request_resume(device->dev);
 220}
 221
 222static int __acpi_power_on(struct acpi_power_resource *resource)
 223{
 224        struct acpi_power_resource_device *device_list = resource->devices;
 225        acpi_status status = AE_OK;
 226
 227        status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
 228        if (ACPI_FAILURE(status))
 229                return -ENODEV;
 230
 231        /* Update the power resource's _device_ power state */
 232        resource->device->power.state = ACPI_STATE_D0;
 233
 234        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",
 235                          resource->name));
 236
 237        while (device_list) {
 238                acpi_power_on_device(device_list->device);
 239
 240                device_list = device_list->next;
 241        }
 242
 243        return 0;
 244}
 245
 246static int acpi_power_on(acpi_handle handle)
 247{
 248        int result = 0;
 249        struct acpi_power_resource *resource = NULL;
 250
 251        result = acpi_power_get_context(handle, &resource);
 252        if (result)
 253                return result;
 254
 255        mutex_lock(&resource->resource_lock);
 256
 257        if (resource->ref_count++) {
 258                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 259                                  "Power resource [%s] already on",
 260                                  resource->name));
 261        } else {
 262                result = __acpi_power_on(resource);
 263                if (result)
 264                        resource->ref_count--;
 265        }
 266
 267        mutex_unlock(&resource->resource_lock);
 268
 269        return result;
 270}
 271
 272static int acpi_power_off(acpi_handle handle)
 273{
 274        int result = 0;
 275        acpi_status status = AE_OK;
 276        struct acpi_power_resource *resource = NULL;
 277
 278        result = acpi_power_get_context(handle, &resource);
 279        if (result)
 280                return result;
 281
 282        mutex_lock(&resource->resource_lock);
 283
 284        if (!resource->ref_count) {
 285                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 286                                  "Power resource [%s] already off",
 287                                  resource->name));
 288                goto unlock;
 289        }
 290
 291        if (--resource->ref_count) {
 292                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 293                                  "Power resource [%s] still in use\n",
 294                                  resource->name));
 295                goto unlock;
 296        }
 297
 298        status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL);
 299        if (ACPI_FAILURE(status)) {
 300                result = -ENODEV;
 301        } else {
 302                /* Update the power resource's _device_ power state */
 303                resource->device->power.state = ACPI_STATE_D3;
 304
 305                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 306                                  "Power resource [%s] turned off\n",
 307                                  resource->name));
 308        }
 309
 310 unlock:
 311        mutex_unlock(&resource->resource_lock);
 312
 313        return result;
 314}
 315
 316static void __acpi_power_off_list(struct acpi_handle_list *list, int num_res)
 317{
 318        int i;
 319
 320        for (i = num_res - 1; i >= 0 ; i--)
 321                acpi_power_off(list->handles[i]);
 322}
 323
 324static void acpi_power_off_list(struct acpi_handle_list *list)
 325{
 326        __acpi_power_off_list(list, list->count);
 327}
 328
 329static int acpi_power_on_list(struct acpi_handle_list *list)
 330{
 331        int result = 0;
 332        int i;
 333
 334        for (i = 0; i < list->count; i++) {
 335                result = acpi_power_on(list->handles[i]);
 336                if (result) {
 337                        __acpi_power_off_list(list, i);
 338                        break;
 339                }
 340        }
 341
 342        return result;
 343}
 344
 345static void __acpi_power_resource_unregister_device(struct device *dev,
 346                acpi_handle res_handle)
 347{
 348        struct acpi_power_resource *resource = NULL;
 349        struct acpi_power_resource_device *prev, *curr;
 350
 351        if (acpi_power_get_context(res_handle, &resource))
 352                return;
 353
 354        mutex_lock(&resource->resource_lock);
 355        prev = NULL;
 356        curr = resource->devices;
 357        while (curr) {
 358                if (curr->device->dev == dev) {
 359                        if (!prev)
 360                                resource->devices = curr->next;
 361                        else
 362                                prev->next = curr->next;
 363
 364                        kfree(curr);
 365                        break;
 366                }
 367
 368                prev = curr;
 369                curr = curr->next;
 370        }
 371        mutex_unlock(&resource->resource_lock);
 372}
 373
 374/* Unlink dev from all power resources in _PR0 */
 375void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle)
 376{
 377        struct acpi_device *acpi_dev;
 378        struct acpi_handle_list *list;
 379        int i;
 380
 381        if (!dev || !handle)
 382                return;
 383
 384        if (acpi_bus_get_device(handle, &acpi_dev))
 385                return;
 386
 387        list = &acpi_dev->power.states[ACPI_STATE_D0].resources;
 388
 389        for (i = 0; i < list->count; i++)
 390                __acpi_power_resource_unregister_device(dev,
 391                        list->handles[i]);
 392}
 393
 394static int __acpi_power_resource_register_device(
 395        struct acpi_power_managed_device *powered_device, acpi_handle handle)
 396{
 397        struct acpi_power_resource *resource = NULL;
 398        struct acpi_power_resource_device *power_resource_device;
 399        int result;
 400
 401        result = acpi_power_get_context(handle, &resource);
 402        if (result)
 403                return result;
 404
 405        power_resource_device = kzalloc(
 406                sizeof(*power_resource_device), GFP_KERNEL);
 407        if (!power_resource_device)
 408                return -ENOMEM;
 409
 410        power_resource_device->device = powered_device;
 411
 412        mutex_lock(&resource->resource_lock);
 413        power_resource_device->next = resource->devices;
 414        resource->devices = power_resource_device;
 415        mutex_unlock(&resource->resource_lock);
 416
 417        return 0;
 418}
 419
 420/* Link dev to all power resources in _PR0 */
 421int acpi_power_resource_register_device(struct device *dev, acpi_handle handle)
 422{
 423        struct acpi_device *acpi_dev;
 424        struct acpi_handle_list *list;
 425        struct acpi_power_managed_device *powered_device;
 426        int i, ret;
 427
 428        if (!dev || !handle)
 429                return -ENODEV;
 430
 431        ret = acpi_bus_get_device(handle, &acpi_dev);
 432        if (ret)
 433                goto no_power_resource;
 434
 435        if (!acpi_dev->power.flags.power_resources)
 436                goto no_power_resource;
 437
 438        powered_device = kzalloc(sizeof(*powered_device), GFP_KERNEL);
 439        if (!powered_device)
 440                return -ENOMEM;
 441
 442        powered_device->dev = dev;
 443        powered_device->handle = handle;
 444
 445        list = &acpi_dev->power.states[ACPI_STATE_D0].resources;
 446
 447        for (i = 0; i < list->count; i++) {
 448                ret = __acpi_power_resource_register_device(powered_device,
 449                        list->handles[i]);
 450
 451                if (ret) {
 452                        acpi_power_resource_unregister_device(dev, handle);
 453                        break;
 454                }
 455        }
 456
 457        return ret;
 458
 459no_power_resource:
 460        printk(KERN_WARNING PREFIX "Invalid Power Resource to register!");
 461        return -ENODEV;
 462}
 463
 464/**
 465 * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in
 466 *                          ACPI 3.0) _PSW (Power State Wake)
 467 * @dev: Device to handle.
 468 * @enable: 0 - disable, 1 - enable the wake capabilities of the device.
 469 * @sleep_state: Target sleep state of the system.
 470 * @dev_state: Target power state of the device.
 471 *
 472 * Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power
 473 * State Wake) for the device, if present.  On failure reset the device's
 474 * wakeup.flags.valid flag.
 475 *
 476 * RETURN VALUE:
 477 * 0 if either _DSW or _PSW has been successfully executed
 478 * 0 if neither _DSW nor _PSW has been found
 479 * -ENODEV if the execution of either _DSW or _PSW has failed
 480 */
 481int acpi_device_sleep_wake(struct acpi_device *dev,
 482                           int enable, int sleep_state, int dev_state)
 483{
 484        union acpi_object in_arg[3];
 485        struct acpi_object_list arg_list = { 3, in_arg };
 486        acpi_status status = AE_OK;
 487
 488        /*
 489         * Try to execute _DSW first.
 490         *
 491         * Three agruments are needed for the _DSW object:
 492         * Argument 0: enable/disable the wake capabilities
 493         * Argument 1: target system state
 494         * Argument 2: target device state
 495         * When _DSW object is called to disable the wake capabilities, maybe
 496         * the first argument is filled. The values of the other two agruments
 497         * are meaningless.
 498         */
 499        in_arg[0].type = ACPI_TYPE_INTEGER;
 500        in_arg[0].integer.value = enable;
 501        in_arg[1].type = ACPI_TYPE_INTEGER;
 502        in_arg[1].integer.value = sleep_state;
 503        in_arg[2].type = ACPI_TYPE_INTEGER;
 504        in_arg[2].integer.value = dev_state;
 505        status = acpi_evaluate_object(dev->handle, "_DSW", &arg_list, NULL);
 506        if (ACPI_SUCCESS(status)) {
 507                return 0;
 508        } else if (status != AE_NOT_FOUND) {
 509                printk(KERN_ERR PREFIX "_DSW execution failed\n");
 510                dev->wakeup.flags.valid = 0;
 511                return -ENODEV;
 512        }
 513
 514        /* Execute _PSW */
 515        arg_list.count = 1;
 516        in_arg[0].integer.value = enable;
 517        status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
 518        if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
 519                printk(KERN_ERR PREFIX "_PSW execution failed\n");
 520                dev->wakeup.flags.valid = 0;
 521                return -ENODEV;
 522        }
 523
 524        return 0;
 525}
 526
 527/*
 528 * Prepare a wakeup device, two steps (Ref ACPI 2.0:P229):
 529 * 1. Power on the power resources required for the wakeup device 
 530 * 2. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power
 531 *    State Wake) for the device, if present
 532 */
 533int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
 534{
 535        int i, err = 0;
 536
 537        if (!dev || !dev->wakeup.flags.valid)
 538                return -EINVAL;
 539
 540        mutex_lock(&acpi_device_lock);
 541
 542        if (dev->wakeup.prepare_count++)
 543                goto out;
 544
 545        /* Open power resource */
 546        for (i = 0; i < dev->wakeup.resources.count; i++) {
 547                int ret = acpi_power_on(dev->wakeup.resources.handles[i]);
 548                if (ret) {
 549                        printk(KERN_ERR PREFIX "Transition power state\n");
 550                        dev->wakeup.flags.valid = 0;
 551                        err = -ENODEV;
 552                        goto err_out;
 553                }
 554        }
 555
 556        /*
 557         * Passing 3 as the third argument below means the device may be placed
 558         * in arbitrary power state afterwards.
 559         */
 560        err = acpi_device_sleep_wake(dev, 1, sleep_state, 3);
 561
 562 err_out:
 563        if (err)
 564                dev->wakeup.prepare_count = 0;
 565
 566 out:
 567        mutex_unlock(&acpi_device_lock);
 568        return err;
 569}
 570
 571/*
 572 * Shutdown a wakeup device, counterpart of above method
 573 * 1. Execute _DSW (Device Sleep Wake) or (deprecated in ACPI 3.0) _PSW (Power
 574 *    State Wake) for the device, if present
 575 * 2. Shutdown down the power resources
 576 */
 577int acpi_disable_wakeup_device_power(struct acpi_device *dev)
 578{
 579        int i, err = 0;
 580
 581        if (!dev || !dev->wakeup.flags.valid)
 582                return -EINVAL;
 583
 584        mutex_lock(&acpi_device_lock);
 585
 586        if (--dev->wakeup.prepare_count > 0)
 587                goto out;
 588
 589        /*
 590         * Executing the code below even if prepare_count is already zero when
 591         * the function is called may be useful, for example for initialisation.
 592         */
 593        if (dev->wakeup.prepare_count < 0)
 594                dev->wakeup.prepare_count = 0;
 595
 596        err = acpi_device_sleep_wake(dev, 0, 0, 0);
 597        if (err)
 598                goto out;
 599
 600        /* Close power resource */
 601        for (i = 0; i < dev->wakeup.resources.count; i++) {
 602                int ret = acpi_power_off(dev->wakeup.resources.handles[i]);
 603                if (ret) {
 604                        printk(KERN_ERR PREFIX "Transition power state\n");
 605                        dev->wakeup.flags.valid = 0;
 606                        err = -ENODEV;
 607                        goto out;
 608                }
 609        }
 610
 611 out:
 612        mutex_unlock(&acpi_device_lock);
 613        return err;
 614}
 615
 616/* --------------------------------------------------------------------------
 617                             Device Power Management
 618   -------------------------------------------------------------------------- */
 619
 620int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
 621{
 622        int result = 0;
 623        struct acpi_handle_list *list = NULL;
 624        int list_state = 0;
 625        int i = 0;
 626
 627        if (!device || !state)
 628                return -EINVAL;
 629
 630        /*
 631         * We know a device's inferred power state when all the resources
 632         * required for a given D-state are 'on'.
 633         */
 634        for (i = ACPI_STATE_D0; i < ACPI_STATE_D3_HOT; i++) {
 635                list = &device->power.states[i].resources;
 636                if (list->count < 1)
 637                        continue;
 638
 639                result = acpi_power_get_list_state(list, &list_state);
 640                if (result)
 641                        return result;
 642
 643                if (list_state == ACPI_POWER_RESOURCE_STATE_ON) {
 644                        *state = i;
 645                        return 0;
 646                }
 647        }
 648
 649        *state = ACPI_STATE_D3;
 650        return 0;
 651}
 652
 653int acpi_power_on_resources(struct acpi_device *device, int state)
 654{
 655        if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3)
 656                return -EINVAL;
 657
 658        return acpi_power_on_list(&device->power.states[state].resources);
 659}
 660
 661int acpi_power_transition(struct acpi_device *device, int state)
 662{
 663        int result = 0;
 664
 665        if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
 666                return -EINVAL;
 667
 668        if (device->power.state == state)
 669                return 0;
 670
 671        if ((device->power.state < ACPI_STATE_D0)
 672            || (device->power.state > ACPI_STATE_D3_COLD))
 673                return -ENODEV;
 674
 675        /* TBD: Resources must be ordered. */
 676
 677        /*
 678         * First we reference all power resources required in the target list
 679         * (e.g. so the device doesn't lose power while transitioning).  Then,
 680         * we dereference all power resources used in the current list.
 681         */
 682        if (state < ACPI_STATE_D3_COLD)
 683                result = acpi_power_on_list(
 684                        &device->power.states[state].resources);
 685
 686        if (!result && device->power.state < ACPI_STATE_D3_COLD)
 687                acpi_power_off_list(
 688                        &device->power.states[device->power.state].resources);
 689
 690        /* We shouldn't change the state unless the above operations succeed. */
 691        device->power.state = result ? ACPI_STATE_UNKNOWN : state;
 692
 693        return result;
 694}
 695
 696/* --------------------------------------------------------------------------
 697                                Driver Interface
 698   -------------------------------------------------------------------------- */
 699
 700static int acpi_power_add(struct acpi_device *device)
 701{
 702        int result = 0, state;
 703        acpi_status status = AE_OK;
 704        struct acpi_power_resource *resource = NULL;
 705        union acpi_object acpi_object;
 706        struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object };
 707
 708
 709        if (!device)
 710                return -EINVAL;
 711
 712        resource = kzalloc(sizeof(struct acpi_power_resource), GFP_KERNEL);
 713        if (!resource)
 714                return -ENOMEM;
 715
 716        resource->device = device;
 717        mutex_init(&resource->resource_lock);
 718        strcpy(resource->name, device->pnp.bus_id);
 719        strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
 720        strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
 721        device->driver_data = resource;
 722
 723        /* Evalute the object to get the system level and resource order. */
 724        status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer);
 725        if (ACPI_FAILURE(status)) {
 726                result = -ENODEV;
 727                goto end;
 728        }
 729        resource->system_level = acpi_object.power_resource.system_level;
 730        resource->order = acpi_object.power_resource.resource_order;
 731
 732        result = acpi_power_get_state(device->handle, &state);
 733        if (result)
 734                goto end;
 735
 736        switch (state) {
 737        case ACPI_POWER_RESOURCE_STATE_ON:
 738                device->power.state = ACPI_STATE_D0;
 739                break;
 740        case ACPI_POWER_RESOURCE_STATE_OFF:
 741                device->power.state = ACPI_STATE_D3;
 742                break;
 743        default:
 744                device->power.state = ACPI_STATE_UNKNOWN;
 745                break;
 746        }
 747
 748        printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
 749               acpi_device_bid(device), state ? "on" : "off");
 750
 751      end:
 752        if (result)
 753                kfree(resource);
 754
 755        return result;
 756}
 757
 758static int acpi_power_remove(struct acpi_device *device, int type)
 759{
 760        struct acpi_power_resource *resource;
 761
 762        if (!device)
 763                return -EINVAL;
 764
 765        resource = acpi_driver_data(device);
 766        if (!resource)
 767                return -EINVAL;
 768
 769        kfree(resource);
 770
 771        return 0;
 772}
 773
 774static int acpi_power_resume(struct acpi_device *device)
 775{
 776        int result = 0, state;
 777        struct acpi_power_resource *resource;
 778
 779        if (!device)
 780                return -EINVAL;
 781
 782        resource = acpi_driver_data(device);
 783        if (!resource)
 784                return -EINVAL;
 785
 786        mutex_lock(&resource->resource_lock);
 787
 788        result = acpi_power_get_state(device->handle, &state);
 789        if (result)
 790                goto unlock;
 791
 792        if (state == ACPI_POWER_RESOURCE_STATE_OFF && resource->ref_count)
 793                result = __acpi_power_on(resource);
 794
 795 unlock:
 796        mutex_unlock(&resource->resource_lock);
 797
 798        return result;
 799}
 800
 801int __init acpi_power_init(void)
 802{
 803        INIT_LIST_HEAD(&acpi_power_resource_list);
 804        return acpi_bus_register_driver(&acpi_power_driver);
 805}
 806