2
* acpi_power.c - ACPI Bus Power Management ($Revision: 39 $)
4
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
7
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
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.
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.
23
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
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.
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>
47
#define PREFIX "ACPI: "
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
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);
63
static const struct acpi_device_id power_device_ids[] = {
67
MODULE_DEVICE_TABLE(acpi, power_device_ids);
69
static struct acpi_driver acpi_power_driver = {
71
.class = ACPI_POWER_CLASS,
72
.ids = power_device_ids,
74
.add = acpi_power_add,
75
.remove = acpi_power_remove,
76
.resume = acpi_power_resume,
80
struct acpi_power_resource {
81
struct acpi_device * device;
85
unsigned int ref_count;
86
struct mutex resource_lock;
89
static struct list_head acpi_power_resource_list;
91
/* --------------------------------------------------------------------------
92
Power Resource Management
93
-------------------------------------------------------------------------- */
96
acpi_power_get_context(acpi_handle handle,
97
struct acpi_power_resource **resource)
100
struct acpi_device *device = NULL;
106
result = acpi_bus_get_device(handle, &device);
108
printk(KERN_WARNING PREFIX "Getting context [%p]\n", handle);
112
*resource = acpi_driver_data(device);
119
static int acpi_power_get_state(acpi_handle handle, int *state)
121
acpi_status status = AE_OK;
122
unsigned long long sta = 0;
124
struct acpi_buffer buffer = { sizeof(node_name), node_name };
127
if (!handle || !state)
130
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
131
if (ACPI_FAILURE(status))
134
*state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON:
135
ACPI_POWER_RESOURCE_STATE_OFF;
137
acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
139
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
141
*state ? "on" : "off"));
146
static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
154
/* The state of the list is 'on' IFF all resources are 'on'. */
156
for (i = 0; i < list->count; i++) {
157
struct acpi_power_resource *resource;
158
acpi_handle handle = list->handles[i];
161
result = acpi_power_get_context(handle, &resource);
165
mutex_lock(&resource->resource_lock);
167
result = acpi_power_get_state(handle, &cur_state);
169
mutex_unlock(&resource->resource_lock);
174
if (cur_state != ACPI_POWER_RESOURCE_STATE_ON)
178
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n",
179
cur_state ? "on" : "off"));
186
static int __acpi_power_on(struct acpi_power_resource *resource)
188
acpi_status status = AE_OK;
190
status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
191
if (ACPI_FAILURE(status))
194
/* Update the power resource's _device_ power state */
195
resource->device->power.state = ACPI_STATE_D0;
197
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",
203
static int acpi_power_on(acpi_handle handle)
206
struct acpi_power_resource *resource = NULL;
208
result = acpi_power_get_context(handle, &resource);
212
mutex_lock(&resource->resource_lock);
214
if (resource->ref_count++) {
215
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
216
"Power resource [%s] already on",
219
result = __acpi_power_on(resource);
221
resource->ref_count--;
224
mutex_unlock(&resource->resource_lock);
229
static int acpi_power_off(acpi_handle handle)
232
acpi_status status = AE_OK;
233
struct acpi_power_resource *resource = NULL;
235
result = acpi_power_get_context(handle, &resource);
239
mutex_lock(&resource->resource_lock);
241
if (!resource->ref_count) {
242
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
243
"Power resource [%s] already off",
248
if (--resource->ref_count) {
249
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
250
"Power resource [%s] still in use\n",
255
status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL);
256
if (ACPI_FAILURE(status)) {
259
/* Update the power resource's _device_ power state */
260
resource->device->power.state = ACPI_STATE_D3;
262
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
263
"Power resource [%s] turned off\n",
268
mutex_unlock(&resource->resource_lock);
273
static void __acpi_power_off_list(struct acpi_handle_list *list, int num_res)
277
for (i = num_res - 1; i >= 0 ; i--)
278
acpi_power_off(list->handles[i]);
281
static void acpi_power_off_list(struct acpi_handle_list *list)
283
__acpi_power_off_list(list, list->count);
286
static int acpi_power_on_list(struct acpi_handle_list *list)
291
for (i = 0; i < list->count; i++) {
292
result = acpi_power_on(list->handles[i]);
294
__acpi_power_off_list(list, i);
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.
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.
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
319
int acpi_device_sleep_wake(struct acpi_device *dev,
320
int enable, int sleep_state, int dev_state)
322
union acpi_object in_arg[3];
323
struct acpi_object_list arg_list = { 3, in_arg };
324
acpi_status status = AE_OK;
327
* Try to execute _DSW first.
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
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)) {
346
} else if (status != AE_NOT_FOUND) {
347
printk(KERN_ERR PREFIX "_DSW execution failed\n");
348
dev->wakeup.flags.valid = 0;
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;
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
371
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
375
if (!dev || !dev->wakeup.flags.valid)
378
mutex_lock(&acpi_device_lock);
380
if (dev->wakeup.prepare_count++)
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]);
387
printk(KERN_ERR PREFIX "Transition power state\n");
388
dev->wakeup.flags.valid = 0;
395
* Passing 3 as the third argument below means the device may be placed
396
* in arbitrary power state afterwards.
398
err = acpi_device_sleep_wake(dev, 1, sleep_state, 3);
402
dev->wakeup.prepare_count = 0;
405
mutex_unlock(&acpi_device_lock);
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
415
int acpi_disable_wakeup_device_power(struct acpi_device *dev)
419
if (!dev || !dev->wakeup.flags.valid)
422
mutex_lock(&acpi_device_lock);
424
if (--dev->wakeup.prepare_count > 0)
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.
431
if (dev->wakeup.prepare_count < 0)
432
dev->wakeup.prepare_count = 0;
434
err = acpi_device_sleep_wake(dev, 0, 0, 0);
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]);
442
printk(KERN_ERR PREFIX "Transition power state\n");
443
dev->wakeup.flags.valid = 0;
450
mutex_unlock(&acpi_device_lock);
454
/* --------------------------------------------------------------------------
455
Device Power Management
456
-------------------------------------------------------------------------- */
458
int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
461
struct acpi_handle_list *list = NULL;
465
if (!device || !state)
469
* We know a device's inferred power state when all the resources
470
* required for a given D-state are 'on'.
472
for (i = ACPI_STATE_D0; i < ACPI_STATE_D3; i++) {
473
list = &device->power.states[i].resources;
477
result = acpi_power_get_list_state(list, &list_state);
481
if (list_state == ACPI_POWER_RESOURCE_STATE_ON) {
487
*state = ACPI_STATE_D3;
491
int acpi_power_on_resources(struct acpi_device *device, int state)
493
if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3)
496
return acpi_power_on_list(&device->power.states[state].resources);
499
int acpi_power_transition(struct acpi_device *device, int state)
503
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
506
if (device->power.state == state)
509
if ((device->power.state < ACPI_STATE_D0)
510
|| (device->power.state > ACPI_STATE_D3))
513
/* TBD: Resources must be ordered. */
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.
520
result = acpi_power_on_list(&device->power.states[state].resources);
523
&device->power.states[device->power.state].resources);
525
/* We shouldn't change the state unless the above operations succeed. */
526
device->power.state = result ? ACPI_STATE_UNKNOWN : state;
531
/* --------------------------------------------------------------------------
533
-------------------------------------------------------------------------- */
535
static int acpi_power_add(struct acpi_device *device)
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 };
547
resource = kzalloc(sizeof(struct acpi_power_resource), GFP_KERNEL);
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;
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)) {
564
resource->system_level = acpi_object.power_resource.system_level;
565
resource->order = acpi_object.power_resource.resource_order;
567
result = acpi_power_get_state(device->handle, &state);
572
case ACPI_POWER_RESOURCE_STATE_ON:
573
device->power.state = ACPI_STATE_D0;
575
case ACPI_POWER_RESOURCE_STATE_OFF:
576
device->power.state = ACPI_STATE_D3;
579
device->power.state = ACPI_STATE_UNKNOWN;
583
printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
584
acpi_device_bid(device), state ? "on" : "off");
593
static int acpi_power_remove(struct acpi_device *device, int type)
595
struct acpi_power_resource *resource;
600
resource = acpi_driver_data(device);
609
static int acpi_power_resume(struct acpi_device *device)
611
int result = 0, state;
612
struct acpi_power_resource *resource;
617
resource = acpi_driver_data(device);
621
mutex_lock(&resource->resource_lock);
623
result = acpi_power_get_state(device->handle, &state);
627
if (state == ACPI_POWER_RESOURCE_STATE_OFF && resource->ref_count)
628
result = __acpi_power_on(resource);
631
mutex_unlock(&resource->resource_lock);
636
int __init acpi_power_init(void)
638
INIT_LIST_HEAD(&acpi_power_resource_list);
639
return acpi_bus_register_driver(&acpi_power_driver);