mirror of https://gitee.com/openkylin/linux.git
Pull alexey-fixes into release branch
This commit is contained in:
commit
14f7d720bb
|
@ -586,11 +586,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
|
||||
eata= [HW,SCSI]
|
||||
|
||||
ec_intr= [HW,ACPI] ACPI Embedded Controller interrupt mode
|
||||
Format: <int>
|
||||
0: polling mode
|
||||
non-0: interrupt mode (default)
|
||||
|
||||
edd= [EDD]
|
||||
Format: {"of[f]" | "sk[ipmbr]"}
|
||||
See comment in arch/i386/boot/edd.S
|
||||
|
|
|
@ -88,7 +88,8 @@ config ACPI_PROC_EVENT
|
|||
|
||||
config ACPI_AC
|
||||
tristate "AC Adapter"
|
||||
depends on X86 && POWER_SUPPLY
|
||||
depends on X86
|
||||
select POWER_SUPPLY
|
||||
default y
|
||||
help
|
||||
This driver adds support for the AC Adapter object, which indicates
|
||||
|
@ -97,7 +98,8 @@ config ACPI_AC
|
|||
|
||||
config ACPI_BATTERY
|
||||
tristate "Battery"
|
||||
depends on X86 && POWER_SUPPLY
|
||||
depends on X86
|
||||
select POWER_SUPPLY
|
||||
default y
|
||||
help
|
||||
This driver adds support for battery information through
|
||||
|
@ -352,7 +354,7 @@ config ACPI_HOTPLUG_MEMORY
|
|||
config ACPI_SBS
|
||||
tristate "Smart Battery System"
|
||||
depends on X86
|
||||
depends on POWER_SUPPLY
|
||||
select POWER_SUPPLY
|
||||
help
|
||||
This driver adds support for the Smart Battery System, another
|
||||
type of access to battery information, found on some laptops.
|
||||
|
|
|
@ -125,11 +125,15 @@ static int acpi_battery_technology(struct acpi_battery *battery)
|
|||
return POWER_SUPPLY_TECHNOLOGY_NiMH;
|
||||
if (!strcasecmp("LION", battery->type))
|
||||
return POWER_SUPPLY_TECHNOLOGY_LION;
|
||||
if (!strcasecmp("LI-ION", battery->type))
|
||||
return POWER_SUPPLY_TECHNOLOGY_LION;
|
||||
if (!strcasecmp("LiP", battery->type))
|
||||
return POWER_SUPPLY_TECHNOLOGY_LIPO;
|
||||
return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
|
||||
}
|
||||
|
||||
static int acpi_battery_update(struct acpi_battery *battery);
|
||||
|
||||
static int acpi_battery_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
|
@ -139,6 +143,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
|
|||
if ((!acpi_battery_present(battery)) &&
|
||||
psp != POWER_SUPPLY_PROP_PRESENT)
|
||||
return -ENODEV;
|
||||
acpi_battery_update(battery);
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_STATUS:
|
||||
if (battery->state & 0x01)
|
||||
|
@ -257,7 +262,7 @@ static int extract_package(struct acpi_battery *battery,
|
|||
union acpi_object *package,
|
||||
struct acpi_offsets *offsets, int num)
|
||||
{
|
||||
int i, *x;
|
||||
int i;
|
||||
union acpi_object *element;
|
||||
if (package->type != ACPI_TYPE_PACKAGE)
|
||||
return -EFAULT;
|
||||
|
@ -266,16 +271,21 @@ static int extract_package(struct acpi_battery *battery,
|
|||
return -EFAULT;
|
||||
element = &package->package.elements[i];
|
||||
if (offsets[i].mode) {
|
||||
if (element->type != ACPI_TYPE_STRING &&
|
||||
element->type != ACPI_TYPE_BUFFER)
|
||||
return -EFAULT;
|
||||
strncpy((u8 *)battery + offsets[i].offset,
|
||||
element->string.pointer, 32);
|
||||
u8 *ptr = (u8 *)battery + offsets[i].offset;
|
||||
if (element->type == ACPI_TYPE_STRING ||
|
||||
element->type == ACPI_TYPE_BUFFER)
|
||||
strncpy(ptr, element->string.pointer, 32);
|
||||
else if (element->type == ACPI_TYPE_INTEGER) {
|
||||
strncpy(ptr, (u8 *)&element->integer.value,
|
||||
sizeof(acpi_integer));
|
||||
ptr[sizeof(acpi_integer)] = 0;
|
||||
} else return -EFAULT;
|
||||
} else {
|
||||
if (element->type != ACPI_TYPE_INTEGER)
|
||||
return -EFAULT;
|
||||
x = (int *)((u8 *)battery + offsets[i].offset);
|
||||
*x = element->integer.value;
|
||||
if (element->type == ACPI_TYPE_INTEGER) {
|
||||
int *x = (int *)((u8 *)battery +
|
||||
offsets[i].offset);
|
||||
*x = element->integer.value;
|
||||
} else return -EFAULT;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -385,29 +395,81 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
|
|||
return acpi_battery_set_alarm(battery);
|
||||
}
|
||||
|
||||
static ssize_t acpi_battery_alarm_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
|
||||
return sprintf(buf, "%d\n", battery->alarm * 1000);
|
||||
}
|
||||
|
||||
static ssize_t acpi_battery_alarm_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long x;
|
||||
struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
|
||||
if (sscanf(buf, "%ld\n", &x) == 1)
|
||||
battery->alarm = x/1000;
|
||||
if (acpi_battery_present(battery))
|
||||
acpi_battery_set_alarm(battery);
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct device_attribute alarm_attr = {
|
||||
.attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
|
||||
.show = acpi_battery_alarm_show,
|
||||
.store = acpi_battery_alarm_store,
|
||||
};
|
||||
|
||||
static int sysfs_add_battery(struct acpi_battery *battery)
|
||||
{
|
||||
int result;
|
||||
|
||||
battery->update_time = 0;
|
||||
result = acpi_battery_get_info(battery);
|
||||
acpi_battery_init_alarm(battery);
|
||||
if (result)
|
||||
return result;
|
||||
if (battery->power_unit) {
|
||||
battery->bat.properties = charge_battery_props;
|
||||
battery->bat.num_properties =
|
||||
ARRAY_SIZE(charge_battery_props);
|
||||
} else {
|
||||
battery->bat.properties = energy_battery_props;
|
||||
battery->bat.num_properties =
|
||||
ARRAY_SIZE(energy_battery_props);
|
||||
}
|
||||
|
||||
battery->bat.name = acpi_device_bid(battery->device);
|
||||
battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
battery->bat.get_property = acpi_battery_get_property;
|
||||
|
||||
result = power_supply_register(&battery->device->dev, &battery->bat);
|
||||
if (result)
|
||||
return result;
|
||||
return device_create_file(battery->bat.dev, &alarm_attr);
|
||||
}
|
||||
|
||||
static void sysfs_remove_battery(struct acpi_battery *battery)
|
||||
{
|
||||
if (!battery->bat.dev)
|
||||
return;
|
||||
device_remove_file(battery->bat.dev, &alarm_attr);
|
||||
power_supply_unregister(&battery->bat);
|
||||
}
|
||||
|
||||
static int acpi_battery_update(struct acpi_battery *battery)
|
||||
{
|
||||
int saved_present = acpi_battery_present(battery);
|
||||
int result = acpi_battery_get_status(battery);
|
||||
if (result || !acpi_battery_present(battery))
|
||||
if (result)
|
||||
return result;
|
||||
if (saved_present != acpi_battery_present(battery) ||
|
||||
!battery->update_time) {
|
||||
battery->update_time = 0;
|
||||
result = acpi_battery_get_info(battery);
|
||||
if (result)
|
||||
return result;
|
||||
if (battery->power_unit) {
|
||||
battery->bat.properties = charge_battery_props;
|
||||
battery->bat.num_properties =
|
||||
ARRAY_SIZE(charge_battery_props);
|
||||
} else {
|
||||
battery->bat.properties = energy_battery_props;
|
||||
battery->bat.num_properties =
|
||||
ARRAY_SIZE(energy_battery_props);
|
||||
}
|
||||
acpi_battery_init_alarm(battery);
|
||||
if (!acpi_battery_present(battery)) {
|
||||
sysfs_remove_battery(battery);
|
||||
return 0;
|
||||
}
|
||||
if (!battery->bat.dev)
|
||||
sysfs_add_battery(battery);
|
||||
return acpi_battery_get_state(battery);
|
||||
}
|
||||
|
||||
|
@ -554,10 +616,6 @@ static ssize_t acpi_battery_write_alarm(struct file *file,
|
|||
|
||||
if (!battery || (count > sizeof(alarm_string) - 1))
|
||||
return -EINVAL;
|
||||
if (result) {
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
if (!acpi_battery_present(battery)) {
|
||||
result = -ENODEV;
|
||||
goto end;
|
||||
|
@ -688,33 +746,6 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
|
|||
|
||||
#endif
|
||||
|
||||
static ssize_t acpi_battery_alarm_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
|
||||
return sprintf(buf, "%d\n", battery->alarm * 1000);
|
||||
}
|
||||
|
||||
static ssize_t acpi_battery_alarm_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long x;
|
||||
struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
|
||||
if (sscanf(buf, "%ld\n", &x) == 1)
|
||||
battery->alarm = x/1000;
|
||||
if (acpi_battery_present(battery))
|
||||
acpi_battery_set_alarm(battery);
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct device_attribute alarm_attr = {
|
||||
.attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
|
||||
.show = acpi_battery_alarm_show,
|
||||
.store = acpi_battery_alarm_store,
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Driver Interface
|
||||
-------------------------------------------------------------------------- */
|
||||
|
@ -732,7 +763,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
|
|||
acpi_bus_generate_netlink_event(device->pnp.device_class,
|
||||
device->dev.bus_id, event,
|
||||
acpi_battery_present(battery));
|
||||
kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
|
||||
/* acpi_batter_update could remove power_supply object */
|
||||
if (battery->bat.dev)
|
||||
kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
|
||||
}
|
||||
|
||||
static int acpi_battery_add(struct acpi_device *device)
|
||||
|
@ -756,11 +789,6 @@ static int acpi_battery_add(struct acpi_device *device)
|
|||
if (result)
|
||||
goto end;
|
||||
#endif
|
||||
battery->bat.name = acpi_device_bid(device);
|
||||
battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
|
||||
battery->bat.get_property = acpi_battery_get_property;
|
||||
result = power_supply_register(&battery->device->dev, &battery->bat);
|
||||
result = device_create_file(battery->bat.dev, &alarm_attr);
|
||||
status = acpi_install_notify_handler(device->handle,
|
||||
ACPI_ALL_NOTIFY,
|
||||
acpi_battery_notify, battery);
|
||||
|
@ -796,10 +824,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
|
|||
#ifdef CONFIG_ACPI_PROCFS
|
||||
acpi_battery_remove_fs(device);
|
||||
#endif
|
||||
if (battery->bat.dev) {
|
||||
device_remove_file(battery->bat.dev, &alarm_attr);
|
||||
power_supply_unregister(&battery->bat);
|
||||
}
|
||||
sysfs_remove_battery(battery);
|
||||
mutex_destroy(&battery->lock);
|
||||
kfree(battery);
|
||||
return 0;
|
||||
|
@ -813,6 +838,7 @@ static int acpi_battery_resume(struct acpi_device *device)
|
|||
return -EINVAL;
|
||||
battery = acpi_driver_data(device);
|
||||
battery->update_time = 0;
|
||||
acpi_battery_update(battery);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -198,12 +198,10 @@ int acpi_bus_set_power(acpi_handle handle, int state)
|
|||
return -ENODEV;
|
||||
}
|
||||
/*
|
||||
* Get device's current power state if it's unknown
|
||||
* This means device power state isn't initialized or previous setting failed
|
||||
* Get device's current power state
|
||||
*/
|
||||
if ((device->power.state == ACPI_STATE_UNKNOWN) || device->flags.force_power_state)
|
||||
acpi_bus_get_power(device->handle, &device->power.state);
|
||||
if ((state == device->power.state) && !device->flags.force_power_state) {
|
||||
acpi_bus_get_power(device->handle, &device->power.state);
|
||||
if (state == device->power.state) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
|
||||
state));
|
||||
return 0;
|
||||
|
|
|
@ -78,6 +78,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
|
|||
|
||||
static int acpi_button_add(struct acpi_device *device);
|
||||
static int acpi_button_remove(struct acpi_device *device, int type);
|
||||
static int acpi_button_resume(struct acpi_device *device);
|
||||
static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
|
||||
static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
|
||||
|
||||
|
@ -87,6 +88,7 @@ static struct acpi_driver acpi_button_driver = {
|
|||
.ids = button_device_ids,
|
||||
.ops = {
|
||||
.add = acpi_button_add,
|
||||
.resume = acpi_button_resume,
|
||||
.remove = acpi_button_remove,
|
||||
},
|
||||
};
|
||||
|
@ -253,6 +255,19 @@ static int acpi_button_remove_fs(struct acpi_device *device)
|
|||
/* --------------------------------------------------------------------------
|
||||
Driver Interface
|
||||
-------------------------------------------------------------------------- */
|
||||
static int acpi_lid_send_state(struct acpi_button *button)
|
||||
{
|
||||
unsigned long state;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
|
||||
&state);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
/* input layer checks if event is redundant */
|
||||
input_report_switch(button->input, SW_LID, !state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
|
||||
{
|
||||
|
@ -265,15 +280,8 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
|
|||
switch (event) {
|
||||
case ACPI_BUTTON_NOTIFY_STATUS:
|
||||
input = button->input;
|
||||
|
||||
if (button->type == ACPI_BUTTON_TYPE_LID) {
|
||||
struct acpi_handle *handle = button->device->handle;
|
||||
unsigned long state;
|
||||
|
||||
if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
|
||||
NULL, &state)))
|
||||
input_report_switch(input, SW_LID, !state);
|
||||
|
||||
acpi_lid_send_state(button);
|
||||
} else {
|
||||
int keycode = test_bit(KEY_SLEEP, input->keybit) ?
|
||||
KEY_SLEEP : KEY_POWER;
|
||||
|
@ -336,6 +344,17 @@ static int acpi_button_install_notify_handlers(struct acpi_button *button)
|
|||
return ACPI_FAILURE(status) ? -ENODEV : 0;
|
||||
}
|
||||
|
||||
static int acpi_button_resume(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_button *button;
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
button = acpi_driver_data(device);
|
||||
if (button && button->type == ACPI_BUTTON_TYPE_LID)
|
||||
return acpi_lid_send_state(button);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_button_remove_notify_handlers(struct acpi_button *button)
|
||||
{
|
||||
switch (button->type) {
|
||||
|
@ -453,6 +472,8 @@ static int acpi_button_add(struct acpi_device *device)
|
|||
error = input_register_device(input);
|
||||
if (error)
|
||||
goto err_remove_handlers;
|
||||
if (button->type == ACPI_BUTTON_TYPE_LID)
|
||||
acpi_lid_send_state(button);
|
||||
|
||||
if (device->wakeup.flags.valid) {
|
||||
/* Button's GPE is run-wake GPE */
|
||||
|
|
|
@ -65,16 +65,18 @@ enum ec_command {
|
|||
/* EC events */
|
||||
enum ec_event {
|
||||
ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
|
||||
ACPI_EC_EVENT_IBF_0, /* Input buffer empty */
|
||||
ACPI_EC_EVENT_IBF_0, /* Input buffer empty */
|
||||
};
|
||||
|
||||
#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */
|
||||
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
|
||||
|
||||
static enum ec_mode {
|
||||
EC_INTR = 1, /* Output buffer full */
|
||||
EC_POLL, /* Input buffer empty */
|
||||
} acpi_ec_mode = EC_INTR;
|
||||
enum {
|
||||
EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */
|
||||
EC_FLAGS_QUERY_PENDING, /* Query is pending */
|
||||
EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */
|
||||
EC_FLAGS_ONLY_IBF_GPE, /* Expect GPE only for IBF = 0 event */
|
||||
};
|
||||
|
||||
static int acpi_ec_remove(struct acpi_device *device, int type);
|
||||
static int acpi_ec_start(struct acpi_device *device);
|
||||
|
@ -116,9 +118,8 @@ static struct acpi_ec {
|
|||
unsigned long command_addr;
|
||||
unsigned long data_addr;
|
||||
unsigned long global_lock;
|
||||
unsigned long flags;
|
||||
struct mutex lock;
|
||||
atomic_t query_pending;
|
||||
atomic_t event_count;
|
||||
wait_queue_head_t wait;
|
||||
struct list_head list;
|
||||
u8 handlers_installed;
|
||||
|
@ -148,45 +149,54 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
|
|||
outb(data, ec->data_addr);
|
||||
}
|
||||
|
||||
static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event,
|
||||
unsigned old_count)
|
||||
static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
|
||||
{
|
||||
u8 status = acpi_ec_read_status(ec);
|
||||
if (old_count == atomic_read(&ec->event_count))
|
||||
if (test_bit(EC_FLAGS_WAIT_GPE, &ec->flags))
|
||||
return 0;
|
||||
if (event == ACPI_EC_EVENT_OBF_1) {
|
||||
if (status & ACPI_EC_FLAG_OBF)
|
||||
if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
|
||||
return 1;
|
||||
} else if (event == ACPI_EC_EVENT_IBF_0) {
|
||||
if (!(status & ACPI_EC_FLAG_IBF))
|
||||
if (!(acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event,
|
||||
unsigned count, int force_poll)
|
||||
static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
|
||||
{
|
||||
if (unlikely(force_poll) || acpi_ec_mode == EC_POLL) {
|
||||
unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
|
||||
while (time_before(jiffies, delay)) {
|
||||
if (acpi_ec_check_status(ec, event, 0))
|
||||
return 0;
|
||||
if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
|
||||
likely(!force_poll)) {
|
||||
if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
|
||||
msecs_to_jiffies(ACPI_EC_DELAY)))
|
||||
return 0;
|
||||
clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
|
||||
if (acpi_ec_check_status(ec, event)) {
|
||||
if (event == ACPI_EC_EVENT_OBF_1) {
|
||||
/* miss OBF = 1 GPE, don't expect it anymore */
|
||||
printk(KERN_INFO PREFIX "missing OBF_1 confirmation,"
|
||||
"switching to degraded mode.\n");
|
||||
set_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags);
|
||||
} else {
|
||||
/* missing GPEs, switch back to poll mode */
|
||||
printk(KERN_INFO PREFIX "missing IBF_1 confirmations,"
|
||||
"switch off interrupt mode.\n");
|
||||
clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (wait_event_timeout(ec->wait,
|
||||
acpi_ec_check_status(ec, event, count),
|
||||
msecs_to_jiffies(ACPI_EC_DELAY)) ||
|
||||
acpi_ec_check_status(ec, event, 0)) {
|
||||
return 0;
|
||||
} else {
|
||||
printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
|
||||
" status = %d, expect_event = %d\n",
|
||||
acpi_ec_read_status(ec), event);
|
||||
unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
|
||||
clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
|
||||
while (time_before(jiffies, delay)) {
|
||||
if (acpi_ec_check_status(ec, event))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
|
||||
" status = %d, expect_event = %d\n",
|
||||
acpi_ec_read_status(ec), event);
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
|
@ -196,39 +206,42 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
|
|||
int force_poll)
|
||||
{
|
||||
int result = 0;
|
||||
unsigned count = atomic_read(&ec->event_count);
|
||||
set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
|
||||
acpi_ec_write_cmd(ec, command);
|
||||
|
||||
for (; wdata_len > 0; --wdata_len) {
|
||||
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count, force_poll);
|
||||
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
|
||||
if (result) {
|
||||
printk(KERN_ERR PREFIX
|
||||
"write_cmd timeout, command = %d\n", command);
|
||||
goto end;
|
||||
}
|
||||
count = atomic_read(&ec->event_count);
|
||||
set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
|
||||
acpi_ec_write_data(ec, *(wdata++));
|
||||
}
|
||||
|
||||
if (!rdata_len) {
|
||||
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count, force_poll);
|
||||
result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
|
||||
if (result) {
|
||||
printk(KERN_ERR PREFIX
|
||||
"finish-write timeout, command = %d\n", command);
|
||||
goto end;
|
||||
}
|
||||
} else if (command == ACPI_EC_COMMAND_QUERY) {
|
||||
atomic_set(&ec->query_pending, 0);
|
||||
}
|
||||
} else if (command == ACPI_EC_COMMAND_QUERY)
|
||||
clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
|
||||
|
||||
for (; rdata_len > 0; --rdata_len) {
|
||||
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, count, force_poll);
|
||||
if (test_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags))
|
||||
force_poll = 1;
|
||||
result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll);
|
||||
if (result) {
|
||||
printk(KERN_ERR PREFIX "read timeout, command = %d\n",
|
||||
command);
|
||||
goto end;
|
||||
}
|
||||
count = atomic_read(&ec->event_count);
|
||||
/* Don't expect GPE after last read */
|
||||
if (rdata_len > 1)
|
||||
set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
|
||||
*(rdata++) = acpi_ec_read_data(ec);
|
||||
}
|
||||
end:
|
||||
|
@ -258,10 +271,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
|
|||
}
|
||||
}
|
||||
|
||||
/* Make sure GPE is enabled before doing transaction */
|
||||
acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
|
||||
|
||||
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0);
|
||||
status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0);
|
||||
if (status) {
|
||||
printk(KERN_ERR PREFIX
|
||||
"input buffer is not empty, aborting transaction\n");
|
||||
|
@ -435,9 +445,9 @@ EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
|
|||
|
||||
void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
|
||||
{
|
||||
struct acpi_ec_query_handler *handler;
|
||||
struct acpi_ec_query_handler *handler, *tmp;
|
||||
mutex_lock(&ec->lock);
|
||||
list_for_each_entry(handler, &ec->list, node) {
|
||||
list_for_each_entry_safe(handler, tmp, &ec->list, node) {
|
||||
if (query_bit == handler->query_bit) {
|
||||
list_del(&handler->node);
|
||||
kfree(handler);
|
||||
|
@ -476,23 +486,24 @@ static void acpi_ec_gpe_query(void *ec_cxt)
|
|||
static u32 acpi_ec_gpe_handler(void *data)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
u8 value;
|
||||
struct acpi_ec *ec = data;
|
||||
|
||||
atomic_inc(&ec->event_count);
|
||||
|
||||
if (acpi_ec_mode == EC_INTR) {
|
||||
clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
|
||||
if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
|
||||
wake_up(&ec->wait);
|
||||
|
||||
if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) {
|
||||
if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
|
||||
status = acpi_os_execute(OSL_EC_BURST_HANDLER,
|
||||
acpi_ec_gpe_query, ec);
|
||||
} else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) {
|
||||
/* this is non-query, must be confirmation */
|
||||
printk(KERN_INFO PREFIX "non-query interrupt received,"
|
||||
" switching to interrupt mode\n");
|
||||
set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
|
||||
}
|
||||
|
||||
value = acpi_ec_read_status(ec);
|
||||
if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) {
|
||||
atomic_set(&ec->query_pending, 1);
|
||||
status =
|
||||
acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
|
||||
}
|
||||
|
||||
return status == AE_OK ?
|
||||
return ACPI_SUCCESS(status) ?
|
||||
ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -641,13 +652,10 @@ static struct acpi_ec *make_acpi_ec(void)
|
|||
struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
|
||||
if (!ec)
|
||||
return NULL;
|
||||
|
||||
atomic_set(&ec->query_pending, 1);
|
||||
atomic_set(&ec->event_count, 1);
|
||||
ec->flags = 1 << EC_FLAGS_QUERY_PENDING;
|
||||
mutex_init(&ec->lock);
|
||||
init_waitqueue_head(&ec->wait);
|
||||
INIT_LIST_HEAD(&ec->list);
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
@ -741,6 +749,8 @@ static int acpi_ec_add(struct acpi_device *device)
|
|||
acpi_ec_add_fs(device);
|
||||
printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
|
||||
ec->gpe, ec->command_addr, ec->data_addr);
|
||||
printk(KERN_INFO PREFIX "driver started in %s mode\n",
|
||||
(test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -833,7 +843,7 @@ static int acpi_ec_start(struct acpi_device *device)
|
|||
ret = ec_install_handlers(ec);
|
||||
|
||||
/* EC is fully operational, allow queries */
|
||||
atomic_set(&ec->query_pending, 0);
|
||||
clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -924,20 +934,4 @@ static void __exit acpi_ec_exit(void)
|
|||
|
||||
return;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
static int __init acpi_ec_set_intr_mode(char *str)
|
||||
{
|
||||
int intr;
|
||||
|
||||
if (!get_option(&str, &intr))
|
||||
return 0;
|
||||
|
||||
acpi_ec_mode = (intr) ? EC_INTR : EC_POLL;
|
||||
|
||||
printk(KERN_NOTICE PREFIX "%s mode.\n", intr ? "interrupt" : "polling");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("ec_intr=", acpi_ec_set_intr_mode);
|
||||
#endif /* 0 */
|
||||
|
|
|
@ -47,8 +47,6 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
static int acpi_fan_add(struct acpi_device *device);
|
||||
static int acpi_fan_remove(struct acpi_device *device, int type);
|
||||
static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
|
||||
static int acpi_fan_resume(struct acpi_device *device);
|
||||
|
||||
static const struct acpi_device_id fan_device_ids[] = {
|
||||
{"PNP0C0B", 0},
|
||||
|
@ -63,15 +61,9 @@ static struct acpi_driver acpi_fan_driver = {
|
|||
.ops = {
|
||||
.add = acpi_fan_add,
|
||||
.remove = acpi_fan_remove,
|
||||
.suspend = acpi_fan_suspend,
|
||||
.resume = acpi_fan_resume,
|
||||
},
|
||||
};
|
||||
|
||||
struct acpi_fan {
|
||||
struct acpi_device * device;
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
FS Interface (/proc)
|
||||
-------------------------------------------------------------------------- */
|
||||
|
@ -80,12 +72,12 @@ static struct proc_dir_entry *acpi_fan_dir;
|
|||
|
||||
static int acpi_fan_read_state(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_fan *fan = seq->private;
|
||||
struct acpi_device *device = seq->private;
|
||||
int state = 0;
|
||||
|
||||
|
||||
if (fan) {
|
||||
if (acpi_bus_get_power(fan->device->handle, &state))
|
||||
if (device) {
|
||||
if (acpi_bus_get_power(device->handle, &state))
|
||||
seq_printf(seq, "status: ERROR\n");
|
||||
else
|
||||
seq_printf(seq, "status: %s\n",
|
||||
|
@ -105,11 +97,10 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
|
|||
{
|
||||
int result = 0;
|
||||
struct seq_file *m = file->private_data;
|
||||
struct acpi_fan *fan = m->private;
|
||||
struct acpi_device *device = m->private;
|
||||
char state_string[12] = { '\0' };
|
||||
|
||||
|
||||
if (!fan || (count > sizeof(state_string) - 1))
|
||||
if (count > sizeof(state_string) - 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(state_string, buffer, count))
|
||||
|
@ -117,7 +108,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
|
|||
|
||||
state_string[count] = '\0';
|
||||
|
||||
result = acpi_bus_set_power(fan->device->handle,
|
||||
result = acpi_bus_set_power(device->handle,
|
||||
simple_strtoul(state_string, NULL, 0));
|
||||
if (result)
|
||||
return result;
|
||||
|
@ -158,7 +149,7 @@ static int acpi_fan_add_fs(struct acpi_device *device)
|
|||
return -ENODEV;
|
||||
else {
|
||||
entry->proc_fops = &acpi_fan_state_ops;
|
||||
entry->data = acpi_driver_data(device);
|
||||
entry->data = device;
|
||||
entry->owner = THIS_MODULE;
|
||||
}
|
||||
|
||||
|
@ -191,14 +182,8 @@ static int acpi_fan_add(struct acpi_device *device)
|
|||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
fan = kzalloc(sizeof(struct acpi_fan), GFP_KERNEL);
|
||||
if (!fan)
|
||||
return -ENOMEM;
|
||||
|
||||
fan->device = device;
|
||||
strcpy(acpi_device_name(device), "Fan");
|
||||
strcpy(acpi_device_class(device), ACPI_FAN_CLASS);
|
||||
acpi_driver_data(device) = fan;
|
||||
|
||||
result = acpi_bus_get_power(device->handle, &state);
|
||||
if (result) {
|
||||
|
@ -206,10 +191,6 @@ static int acpi_fan_add(struct acpi_device *device)
|
|||
goto end;
|
||||
}
|
||||
|
||||
device->flags.force_power_state = 1;
|
||||
acpi_bus_set_power(device->handle, state);
|
||||
device->flags.force_power_state = 0;
|
||||
|
||||
result = acpi_fan_add_fs(device);
|
||||
if (result)
|
||||
goto end;
|
||||
|
@ -227,53 +208,14 @@ static int acpi_fan_add(struct acpi_device *device)
|
|||
|
||||
static int acpi_fan_remove(struct acpi_device *device, int type)
|
||||
{
|
||||
struct acpi_fan *fan = NULL;
|
||||
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
|
||||
fan = acpi_driver_data(device);
|
||||
|
||||
acpi_fan_remove_fs(device);
|
||||
|
||||
kfree(fan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
|
||||
{
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
acpi_bus_set_power(device->handle, ACPI_STATE_D0);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static int acpi_fan_resume(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
int power_state = 0;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
result = acpi_bus_get_power(device->handle, &power_state);
|
||||
if (result) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
|
||||
"Error reading fan power state\n"));
|
||||
return result;
|
||||
}
|
||||
|
||||
device->flags.force_power_state = 1;
|
||||
acpi_bus_set_power(device->handle, power_state);
|
||||
device->flags.force_power_state = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int __init acpi_fan_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
|
|
|
@ -86,7 +86,6 @@ struct acpi_power_resource {
|
|||
acpi_bus_id name;
|
||||
u32 system_level;
|
||||
u32 order;
|
||||
int state;
|
||||
struct mutex resource_lock;
|
||||
struct list_head reference;
|
||||
};
|
||||
|
@ -128,33 +127,31 @@ acpi_power_get_context(acpi_handle handle,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_power_get_state(struct acpi_power_resource *resource)
|
||||
static int acpi_power_get_state(struct acpi_power_resource *resource, int *state)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
unsigned long sta = 0;
|
||||
|
||||
|
||||
if (!resource)
|
||||
if (!resource || !state)
|
||||
return -EINVAL;
|
||||
|
||||
status = acpi_evaluate_integer(resource->device->handle, "_STA", NULL, &sta);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
if (sta & 0x01)
|
||||
resource->state = ACPI_POWER_RESOURCE_STATE_ON;
|
||||
else
|
||||
resource->state = ACPI_POWER_RESOURCE_STATE_OFF;
|
||||
*state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON:
|
||||
ACPI_POWER_RESOURCE_STATE_OFF;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
|
||||
resource->name, resource->state ? "on" : "off"));
|
||||
resource->name, state ? "on" : "off"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
|
||||
{
|
||||
int result = 0;
|
||||
int result = 0, state1;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
u32 i = 0;
|
||||
|
||||
|
@ -168,11 +165,11 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
|
|||
result = acpi_power_get_context(list->handles[i], &resource);
|
||||
if (result)
|
||||
return result;
|
||||
result = acpi_power_get_state(resource);
|
||||
result = acpi_power_get_state(resource, &state1);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
*state = resource->state;
|
||||
*state = state1;
|
||||
|
||||
if (*state != ACPI_POWER_RESOURCE_STATE_ON)
|
||||
break;
|
||||
|
@ -186,7 +183,7 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
|
|||
|
||||
static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
|
||||
{
|
||||
int result = 0;
|
||||
int result = 0, state;
|
||||
int found = 0;
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
|
@ -224,20 +221,14 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
|
|||
}
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
|
||||
if (resource->state == ACPI_POWER_RESOURCE_STATE_ON) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n",
|
||||
resource->name));
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
result = acpi_power_get_state(resource);
|
||||
result = acpi_power_get_state(resource, &state);
|
||||
if (result)
|
||||
return result;
|
||||
if (resource->state != ACPI_POWER_RESOURCE_STATE_ON)
|
||||
if (state != ACPI_POWER_RESOURCE_STATE_ON)
|
||||
return -ENOEXEC;
|
||||
|
||||
/* Update the power resource's _device_ power state */
|
||||
|
@ -250,7 +241,7 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
|
|||
|
||||
static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
|
||||
{
|
||||
int result = 0;
|
||||
int result = 0, state;
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
struct list_head *node, *next;
|
||||
|
@ -281,20 +272,14 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
|
|||
}
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
|
||||
if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
|
||||
resource->name));
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
result = acpi_power_get_state(resource);
|
||||
result = acpi_power_get_state(resource, &state);
|
||||
if (result)
|
||||
return result;
|
||||
if (resource->state != ACPI_POWER_RESOURCE_STATE_OFF)
|
||||
if (state != ACPI_POWER_RESOURCE_STATE_OFF)
|
||||
return -ENOEXEC;
|
||||
|
||||
/* Update the power resource's _device_ power state */
|
||||
|
@ -494,7 +479,7 @@ static struct proc_dir_entry *acpi_power_dir;
|
|||
static int acpi_power_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
int count = 0;
|
||||
int result = 0;
|
||||
int result = 0, state;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
struct list_head *node, *next;
|
||||
struct acpi_power_reference *ref;
|
||||
|
@ -505,12 +490,12 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
|
|||
if (!resource)
|
||||
goto end;
|
||||
|
||||
result = acpi_power_get_state(resource);
|
||||
result = acpi_power_get_state(resource, &state);
|
||||
if (result)
|
||||
goto end;
|
||||
|
||||
seq_puts(seq, "state: ");
|
||||
switch (resource->state) {
|
||||
switch (state) {
|
||||
case ACPI_POWER_RESOURCE_STATE_ON:
|
||||
seq_puts(seq, "on\n");
|
||||
break;
|
||||
|
@ -591,7 +576,7 @@ static int acpi_power_remove_fs(struct acpi_device *device)
|
|||
|
||||
static int acpi_power_add(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
int result = 0, state;
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
union acpi_object acpi_object;
|
||||
|
@ -622,11 +607,11 @@ static int acpi_power_add(struct acpi_device *device)
|
|||
resource->system_level = acpi_object.power_resource.system_level;
|
||||
resource->order = acpi_object.power_resource.resource_order;
|
||||
|
||||
result = acpi_power_get_state(resource);
|
||||
result = acpi_power_get_state(resource, &state);
|
||||
if (result)
|
||||
goto end;
|
||||
|
||||
switch (resource->state) {
|
||||
switch (state) {
|
||||
case ACPI_POWER_RESOURCE_STATE_ON:
|
||||
device->power.state = ACPI_STATE_D0;
|
||||
break;
|
||||
|
@ -643,7 +628,7 @@ static int acpi_power_add(struct acpi_device *device)
|
|||
goto end;
|
||||
|
||||
printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
|
||||
acpi_device_bid(device), resource->state ? "on" : "off");
|
||||
acpi_device_bid(device), state ? "on" : "off");
|
||||
|
||||
end:
|
||||
if (result)
|
||||
|
@ -680,7 +665,7 @@ static int acpi_power_remove(struct acpi_device *device, int type)
|
|||
|
||||
static int acpi_power_resume(struct acpi_device *device)
|
||||
{
|
||||
int result = 0;
|
||||
int result = 0, state;
|
||||
struct acpi_power_resource *resource = NULL;
|
||||
struct acpi_power_reference *ref;
|
||||
|
||||
|
@ -689,12 +674,12 @@ static int acpi_power_resume(struct acpi_device *device)
|
|||
|
||||
resource = (struct acpi_power_resource *)acpi_driver_data(device);
|
||||
|
||||
result = acpi_power_get_state(resource);
|
||||
result = acpi_power_get_state(resource, &state);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
mutex_lock(&resource->resource_lock);
|
||||
if ((resource->state == ACPI_POWER_RESOURCE_STATE_OFF) &&
|
||||
if (state == ACPI_POWER_RESOURCE_STATE_OFF &&
|
||||
!list_empty(&resource->reference)) {
|
||||
ref = container_of(resource->reference.next, struct acpi_power_reference, node);
|
||||
mutex_unlock(&resource->resource_lock);
|
||||
|
|
|
@ -167,8 +167,8 @@ static void acpi_pm_finish(void)
|
|||
{
|
||||
u32 acpi_state = acpi_target_sleep_state;
|
||||
|
||||
acpi_leave_sleep_state(acpi_state);
|
||||
acpi_disable_wakeup_device(acpi_state);
|
||||
acpi_leave_sleep_state(acpi_state);
|
||||
|
||||
/* reset firmware waking vector */
|
||||
acpi_set_firmware_waking_vector((acpi_physical_address) 0);
|
||||
|
@ -272,8 +272,8 @@ static void acpi_hibernation_finish(void)
|
|||
* enable it here.
|
||||
*/
|
||||
acpi_enable();
|
||||
acpi_leave_sleep_state(ACPI_STATE_S4);
|
||||
acpi_disable_wakeup_device(ACPI_STATE_S4);
|
||||
acpi_leave_sleep_state(ACPI_STATE_S4);
|
||||
|
||||
/* reset firmware waking vector */
|
||||
acpi_set_firmware_waking_vector((acpi_physical_address) 0);
|
||||
|
@ -410,6 +410,7 @@ static void acpi_power_off(void)
|
|||
/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
|
||||
printk("%s called\n", __FUNCTION__);
|
||||
local_irq_disable();
|
||||
acpi_enable_wakeup_device(ACPI_STATE_S5);
|
||||
acpi_enter_sleep_state(ACPI_STATE_S5);
|
||||
}
|
||||
|
||||
|
|
|
@ -168,8 +168,7 @@ struct acpi_device_flags {
|
|||
u32 power_manageable:1;
|
||||
u32 performance_manageable:1;
|
||||
u32 wake_capable:1; /* Wakeup(_PRW) supported? */
|
||||
u32 force_power_state:1;
|
||||
u32 reserved:19;
|
||||
u32 reserved:20;
|
||||
};
|
||||
|
||||
/* File System */
|
||||
|
|
Loading…
Reference in New Issue