~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/acpi/power.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

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