Commit 43cdcef6 authored by Len Brown's avatar Len Brown

Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.7

into intel.com:/home/lenb/src/linux-acpi-test-2.6.8
parents f642d8b5 78fbd8ba
......@@ -32,6 +32,7 @@
#include <linux/compiler.h>
#include <linux/acpi.h>
#include <linux/sysdev.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/desc.h>
......@@ -2262,6 +2263,98 @@ static int __init io_apic_bug_finalize(void)
late_initcall(io_apic_bug_finalize);
struct sysfs_ioapic_data {
struct sys_device dev;
struct IO_APIC_route_entry entry[0];
};
static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS];
static int ioapic_suspend(struct sys_device *dev, u32 state)
{
struct IO_APIC_route_entry *entry;
struct sysfs_ioapic_data *data;
unsigned long flags;
int i;
data = container_of(dev, struct sysfs_ioapic_data, dev);
entry = data->entry;
spin_lock_irqsave(&ioapic_lock, flags);
for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
*(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i);
*(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i);
}
spin_unlock_irqrestore(&ioapic_lock, flags);
return 0;
}
static int ioapic_resume(struct sys_device *dev)
{
struct IO_APIC_route_entry *entry;
struct sysfs_ioapic_data *data;
unsigned long flags;
union IO_APIC_reg_00 reg_00;
int i;
data = container_of(dev, struct sysfs_ioapic_data, dev);
entry = data->entry;
spin_lock_irqsave(&ioapic_lock, flags);
reg_00.raw = io_apic_read(dev->id, 0);
if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) {
reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid;
io_apic_write(dev->id, 0, reg_00.raw);
}
for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1));
io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0));
}
spin_unlock_irqrestore(&ioapic_lock, flags);
return 0;
}
static struct sysdev_class ioapic_sysdev_class = {
set_kset_name("ioapic"),
.suspend = ioapic_suspend,
.resume = ioapic_resume,
};
static int __init ioapic_init_sysfs(void)
{
struct sys_device * dev;
int i, size, error = 0;
error = sysdev_class_register(&ioapic_sysdev_class);
if (error)
return error;
for (i = 0; i < nr_ioapics; i++ ) {
size = sizeof(struct sys_device) + nr_ioapic_registers[i]
* sizeof(struct IO_APIC_route_entry);
mp_ioapic_data[i] = kmalloc(size, GFP_KERNEL);
if (!mp_ioapic_data[i]) {
printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
continue;
}
memset(mp_ioapic_data[i], 0, size);
dev = &mp_ioapic_data[i]->dev;
dev->id = i;
dev->cls = &ioapic_sysdev_class;
error = sysdev_register(dev);
if (error) {
kfree(mp_ioapic_data[i]);
mp_ioapic_data[i] = NULL;
printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
continue;
}
}
return 0;
}
device_initcall(ioapic_init_sysfs);
/* --------------------------------------------------------------------------
ACPI-based IOAPIC Configuration
-------------------------------------------------------------------------- */
......
......@@ -288,6 +288,86 @@ acpi_power_off_device (
return_VALUE(0);
}
/*
* Prepare a wakeup device, two steps (Ref ACPI 2.0:P229):
* 1. Power on the power resources required for the wakeup device
* 2. Enable _PSW (power state wake) for the device if present
*/
int acpi_enable_wakeup_device_power (struct acpi_device *dev)
{
union acpi_object arg = {ACPI_TYPE_INTEGER};
struct acpi_object_list arg_list = {1, &arg};
acpi_status status = AE_OK;
int i;
int ret = 0;
ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_power");
if (!dev || !dev->wakeup.flags.valid)
return -1;
arg.integer.value = 1;
/* Open power resource */
for (i = 0; i < dev->wakeup.resources.count; i++) {
ret = acpi_power_on(dev->wakeup.resources.handles[i]);
if (ret) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Error transition power state\n"));
dev->wakeup.flags.valid = 0;
return -1;
}
}
/* Execute PSW */
status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluate _PSW\n"));
dev->wakeup.flags.valid = 0;
ret = -1;
}
return ret;
}
/*
* Shutdown a wakeup device, counterpart of above method
* 1. Disable _PSW (power state wake)
* 2. Shutdown down the power resources
*/
int acpi_disable_wakeup_device_power (struct acpi_device *dev)
{
union acpi_object arg = {ACPI_TYPE_INTEGER};
struct acpi_object_list arg_list = {1, &arg};
acpi_status status = AE_OK;
int i;
int ret = 0;
ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device_power");
if (!dev || !dev->wakeup.flags.valid)
return -1;
arg.integer.value = 0;
/* Execute PSW */
status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluate _PSW\n"));
dev->wakeup.flags.valid = 0;
return -1;
}
/* Close power resource */
for (i = 0; i < dev->wakeup.resources.count; i++) {
ret = acpi_power_off_device(dev->wakeup.resources.handles[i]);
if (ret) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Error transition power state\n"));
dev->wakeup.flags.valid = 0;
return -1;
}
}
return ret;
}
/* --------------------------------------------------------------------------
Device Power Management
......
......@@ -23,7 +23,8 @@ extern struct acpi_device *acpi_root;
#define ACPI_BUS_DEVICE_NAME "System Bus"
static LIST_HEAD(acpi_device_list);
static spinlock_t acpi_device_lock = SPIN_LOCK_UNLOCKED;
spinlock_t acpi_device_lock = SPIN_LOCK_UNLOCKED;
LIST_HEAD(acpi_wakeup_device_list);
static void acpi_device_release(struct kobject * kobj)
{
......@@ -115,9 +116,6 @@ acpi_bus_get_power_flags (
status = acpi_get_handle(device->handle, "_IRC", &handle);
if (ACPI_SUCCESS(status))
device->power.flags.inrush_current = 1;
status = acpi_get_handle(device->handle, "_PRW", &handle);
if (ACPI_SUCCESS(status))
device->power.flags.wake_capable = 1;
/*
* Enumerate supported power management states
......@@ -163,6 +161,125 @@ acpi_bus_get_power_flags (
return 0;
}
static int
acpi_match_ids (
struct acpi_device *device,
char *ids)
{
int error = 0;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
if (device->flags.hardware_id)
if (strstr(ids, device->pnp.hardware_id))
goto Done;
if (device->flags.compatible_ids) {
struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
int i;
/* compare multiple _CID entries against driver ids */
for (i = 0; i < cid_list->count; i++)
{
if (strstr(ids, cid_list->id[i].value))
goto Done;
}
}
error = -ENOENT;
Done:
if (buffer.pointer)
acpi_os_free(buffer.pointer);
return error;
}
static acpi_status
acpi_bus_extract_wakeup_device_power_package (
struct acpi_device *device,
union acpi_object *package)
{
int i = 0;
union acpi_object *element = NULL;
if (!device || !package || (package->package.count < 2))
return AE_BAD_PARAMETER;
element = &(package->package.elements[0]);
if (element->type == ACPI_TYPE_PACKAGE) {
if ((element->package.count < 2) ||
(element->package.elements[0].type != ACPI_TYPE_LOCAL_REFERENCE) ||
(element->package.elements[1].type != ACPI_TYPE_INTEGER))
return AE_BAD_DATA;
device->wakeup.gpe_device = element->package.elements[0].reference.handle;
device->wakeup.gpe_number = (u32)element->package.elements[1].integer.value;
}else if (element->type == ACPI_TYPE_INTEGER) {
device->wakeup.gpe_number = element->integer.value;
}else
return AE_BAD_DATA;
element = &(package->package.elements[1]);
if (element->type != ACPI_TYPE_INTEGER) {
return AE_BAD_DATA;
}
device->wakeup.sleep_state = element->integer.value;
if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
return AE_NO_MEMORY;
}
device->wakeup.resources.count = package->package.count - 2;
for (i=0; i < device->wakeup.resources.count; i++) {
element = &(package->package.elements[i + 2]);
if (element->type != ACPI_TYPE_ANY ) {
return AE_BAD_DATA;
}
device->wakeup.resources.handles[i] = element->reference.handle;
}
return AE_OK;
}
static int
acpi_bus_get_wakeup_device_flags (
struct acpi_device *device)
{
acpi_status status = 0;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
union acpi_object *package = NULL;
ACPI_FUNCTION_TRACE("acpi_bus_get_wakeup_flags");
/* _PRW */
status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRW\n"));
goto end;
}
package = (union acpi_object *) buffer.pointer;
status = acpi_bus_extract_wakeup_device_power_package(device, package);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _PRW package\n"));
goto end;
}
acpi_os_free(buffer.pointer);
device->wakeup.flags.valid = 1;
/* Power button, Lid switch always enable wakeup*/
if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E"))
device->wakeup.flags.run_wake = 1;
/* TBD: lock */
INIT_LIST_HEAD(&device->wakeup_list);
spin_lock(&acpi_device_lock);
list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
spin_unlock(&acpi_device_lock);
end:
if (ACPI_FAILURE(status))
device->flags.wake_capable = 0;
return 0;
}
/* --------------------------------------------------------------------------
Performance Management
......@@ -195,30 +312,7 @@ acpi_bus_match (
struct acpi_device *device,
struct acpi_driver *driver)
{
int error = 0;
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
if (device->flags.hardware_id)
if (strstr(driver->ids, device->pnp.hardware_id))
goto Done;
if (device->flags.compatible_ids) {
struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
int i;
/* compare multiple _CID entries against driver ids */
for (i = 0; i < cid_list->count; i++)
{
if (strstr(driver->ids, cid_list->id[i].value))
goto Done;
}
}
error = -ENOENT;
Done:
if (buffer.pointer)
acpi_os_free(buffer.pointer);
return error;
return acpi_match_ids(device, driver->ids);
}
......@@ -469,6 +563,11 @@ acpi_bus_get_flags (
if (ACPI_SUCCESS(status))
device->flags.power_manageable = 1;
/* Presence of _PRW indicates wake capable */
status = acpi_get_handle(device->handle, "_PRW", &temp);
if (ACPI_SUCCESS(status))
device->flags.wake_capable = 1;
/* TBD: Peformance management */
return_VALUE(0);
......@@ -740,6 +839,16 @@ acpi_bus_add (
goto end;
}
/*
* Wakeup device management
*-----------------------
*/
if (device->flags.wake_capable) {
result = acpi_bus_get_wakeup_device_flags(device);
if (result)
goto end;
}
/*
* Performance Management
* ----------------------
......
obj-y := poweroff.o
obj-$(CONFIG_ACPI_SLEEP) += main.o
obj-$(CONFIG_ACPI_SLEEP) += main.o wakeup.o
obj-$(CONFIG_ACPI_SLEEP_PROC_FS) += proc.o
EXTRA_CFLAGS += $(ACPI_CFLAGS)
......@@ -59,6 +59,7 @@ static int acpi_pm_prepare(u32 pm_state)
(acpi_physical_address) acpi_wakeup_address);
}
ACPI_FLUSH_CPU_CACHE();
acpi_enable_wakeup_device_prep(acpi_state);
acpi_enter_sleep_state_prep(acpi_state);
return 0;
}
......@@ -90,6 +91,7 @@ static int acpi_pm_enter(u32 pm_state)
local_irq_save(flags);
acpi_enable_wakeup_device(acpi_state);
switch (pm_state)
{
case PM_SUSPEND_STANDBY:
......@@ -139,6 +141,7 @@ static int acpi_pm_finish(u32 pm_state)
u32 acpi_state = acpi_suspend_states[pm_state];
acpi_leave_sleep_state(acpi_state);
acpi_disable_wakeup_device(acpi_state);
/* reset firmware waking vector */
acpi_set_firmware_waking_vector((acpi_physical_address) 0);
......
......@@ -15,6 +15,7 @@
#define ACPI_SYSTEM_FILE_SLEEP "sleep"
#define ACPI_SYSTEM_FILE_ALARM "alarm"
#define ACPI_SYSTEM_FILE_WAKEUP_DEVICE "wakeup"
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME ("sleep")
......@@ -352,6 +353,84 @@ acpi_system_write_alarm (
return_VALUE(result ? result : count);
}
extern struct list_head acpi_wakeup_device_list;
extern spinlock_t acpi_device_lock;
static int
acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
{
struct list_head * node, * next;
seq_printf(seq, "Device Sleep state Status\n");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device * dev = container_of(node, struct acpi_device, wakeup_list);
if (!dev->wakeup.flags.valid)
continue;
spin_unlock(&acpi_device_lock);
if (dev->wakeup.flags.run_wake)
seq_printf(seq, "%4s %4d %8s\n",
dev->pnp.bus_id, (u32) dev->wakeup.sleep_state,
dev->wakeup.state.enabled ? "*enabled" : "*disabled");
else
seq_printf(seq, "%4s %4d %8s\n",
dev->pnp.bus_id, (u32) dev->wakeup.sleep_state,
dev->wakeup.state.enabled ? "enabled" : "disabled");
spin_lock(&acpi_device_lock);
}
spin_unlock(&acpi_device_lock);
return 0;
}
static int
acpi_system_write_wakeup_device (
struct file *file,
const char *buffer,
size_t count,
loff_t *ppos)
{
struct list_head * node, * next;
char strbuf[5];
char str[5] = "";
int len = count;
if (len > 4) len = 4;
if (copy_from_user(strbuf, buffer, len))
return -EFAULT;
strbuf[len] = '\0';
sscanf(strbuf, "%s", str);
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device * dev = container_of(node, struct acpi_device, wakeup_list);
if (!dev->wakeup.flags.valid)
continue;
if (!strncmp(dev->pnp.bus_id, str, 4)) {
dev->wakeup.state.enabled = dev->wakeup.state.enabled ? 0:1;
break;
}
}
spin_unlock(&acpi_device_lock);
return count;
}
static int
acpi_system_wakeup_device_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_system_wakeup_device_seq_show, PDE(inode)->data);
}
static struct file_operations acpi_system_wakeup_device_fops = {
.open = acpi_system_wakeup_device_open_fs,
.read = seq_read,
.write = acpi_system_write_wakeup_device,
.llseek = seq_lseek,
.release = single_release,
};
static struct file_operations acpi_system_sleep_fops = {
.open = acpi_system_sleep_open_fs,
......@@ -388,6 +467,13 @@ static int acpi_sleep_proc_init(void)
S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
if (entry)
entry->proc_fops = &acpi_system_alarm_fops;
/* 'wakeup device' [R/W]*/
entry = create_proc_entry(ACPI_SYSTEM_FILE_WAKEUP_DEVICE,
S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
if (entry)
entry->proc_fops = &acpi_system_wakeup_device_fops;
return 0;
}
......
......@@ -2,3 +2,6 @@
extern u8 sleep_states[];
extern int acpi_suspend (u32 state);
extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
extern void acpi_enable_wakeup_device(u8 sleep_state);
extern void acpi_disable_wakeup_device(u8 sleep_state);
/*
* wakeup.c - support wakeup devices
*/
#include <linux/init.h>
#include <linux/acpi.h>
#include <acpi/acpi_drivers.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <acpi/acevents.h>
#include "sleep.h"
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME ("wakeup_devices")
/**
* acpi_enable_wakeup_device_prep - prepare wakeup devices
* @sleep_state: ACPI state
* Enable all wakup devices power if the devices' wakeup level
* is higher than requested sleep level
*/
extern struct list_head acpi_wakeup_device_list;
extern spinlock_t acpi_device_lock;
void
acpi_enable_wakeup_device_prep(
u8 sleep_state)
{
struct list_head * node, * next;
ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_prep");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device * dev = container_of(node,
struct acpi_device, wakeup_list);
if (!dev->wakeup.flags.valid ||
!dev->wakeup.state.enabled ||
(sleep_state > (u32) dev->wakeup.sleep_state))
continue;
spin_unlock(&acpi_device_lock);
acpi_enable_wakeup_device_power(dev);
spin_lock(&acpi_device_lock);
}
spin_unlock(&acpi_device_lock);
}
/**
* acpi_enable_wakeup_device - enable wakeup devices
* @sleep_state: ACPI state
* Enable all wakup devices's GPE
*/
void
acpi_enable_wakeup_device(
u8 sleep_state)
{
struct list_head * node, * next;
/*
* Caution: this routine must be invoked when interrupt is disabled
* Refer ACPI2.0: P212
*/
ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device * dev = container_of(node,
struct acpi_device, wakeup_list);
if (!dev->wakeup.flags.valid ||
!dev->wakeup.state.enabled ||
(sleep_state > (u32) dev->wakeup.sleep_state))
continue;
spin_unlock(&acpi_device_lock);
acpi_enable_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_ISR);
dev->wakeup.state.active = 1;
spin_lock(&acpi_device_lock);
}
spin_unlock(&acpi_device_lock);
}
/**
* acpi_disable_wakeup_device - disable devices' wakeup capability
* @sleep_state: ACPI state
* Disable all wakup devices's GPE and wakeup capability
*/
void
acpi_disable_wakeup_device (
u8 sleep_state)
{
struct list_head * node, * next;
ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device * dev = container_of(node,
struct acpi_device, wakeup_list);
if (!dev->wakeup.flags.valid ||
!dev->wakeup.state.active ||
(sleep_state > (u32) dev->wakeup.sleep_state))
continue;
spin_unlock(&acpi_device_lock);
acpi_disable_wakeup_device_power(dev);
acpi_disable_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_NOT_ISR);
acpi_clear_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_NOT_ISR);
dev->wakeup.state.active = 0;
spin_lock(&acpi_device_lock);
}
spin_unlock(&acpi_device_lock);
}
static int __init acpi_wakeup_device_init(void)
{
struct list_head * node, * next;
printk("ACPI wakeup devices: \n");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device * dev = container_of(node,
struct acpi_device, wakeup_list);
/* Enable wakeup GPE for Lid/sleep button by default */
if (dev->wakeup.flags.run_wake) {
spin_unlock(&acpi_device_lock);
acpi_set_gpe_type(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN);
dev->wakeup.state.enabled = 1;
spin_lock(&acpi_device_lock);
}
printk("%4s ", dev->pnp.bus_id);
}
spin_unlock(&acpi_device_lock);
printk("\n");
return 0;
}
late_initcall(acpi_wakeup_device_init);
......@@ -157,7 +157,8 @@ struct acpi_device_flags {
u32 suprise_removal_ok:1;
u32 power_manageable:1;
u32 performance_manageable:1;
u32 reserved:21;
u32 wake_capable:1; /* Wakeup(_PRW) supported? */
u32 reserved:20;
};
......@@ -203,10 +204,8 @@ struct acpi_device_power_flags {
u32 explicit_get:1; /* _PSC present? */
u32 power_resources:1; /* Power resources */
u32 inrush_current:1; /* Serialize Dx->D0 */
u32 wake_capable:1; /* Wakeup supported? */
u32 wake_enabled:1; /* Enabled for wakeup */
u32 power_removed:1; /* Optimize Dx->D0 */
u32 reserved:26;
u32 reserved:28;
};
struct acpi_device_power_state {
......@@ -250,6 +249,25 @@ struct acpi_device_perf {
struct acpi_device_perf_state *states;
};
/* Wakeup Management */
struct acpi_device_wakeup_flags {
u8 valid:1; /* Can successfully enable wakeup? */
u8 run_wake:1; /* Run-Wake GPE devices */
};
struct acpi_device_wakeup_state {
u8 enabled:1;
u8 active:1;
};
struct acpi_device_wakeup {
acpi_handle gpe_device;
acpi_integer gpe_number;;
acpi_integer sleep_state;
struct acpi_handle_list resources;
struct acpi_device_wakeup_state state;
struct acpi_device_wakeup_flags flags;
};
/* Device */
......@@ -258,11 +276,13 @@ struct acpi_device {
struct acpi_device *parent;
struct list_head children;
struct list_head node;
struct list_head wakeup_list;
struct list_head g_list;
struct acpi_device_status status;
struct acpi_device_flags flags;
struct acpi_device_pnp pnp;
struct acpi_device_power power;
struct acpi_device_wakeup wakeup;
struct acpi_device_perf performance;
struct acpi_device_dir dir;
struct acpi_device_ops ops;
......
......@@ -81,7 +81,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain, int b
-------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_POWER
int acpi_enable_wakeup_device_power (struct acpi_device *dev);
int acpi_disable_wakeup_device_power (struct acpi_device *dev);
int acpi_power_get_inferred_state (struct acpi_device *device);
int acpi_power_transition (struct acpi_device *device, int state);
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment