Commit d5bd8347 authored by Patrick Mochel's avatar Patrick Mochel

[acpi] Replace /proc/acpi/sleep

- Bad to remove proc file now, even though it's nearly useless. Reinstated
  in the name of compatibility. 

- Restored original semantics - if software_suspend() is enabled, then just
  call that (and never go into low-power state). Otherwise, call acpi_suspend().

- acpi_suspend() is simply a wrapper for pm_suspend(), passing down the right
  argument. This is so we don't have to do everything manually anymore.

- Fixed long-standing bug by checking for "4b" in string written in to 
  determine if we want to enter S4bios.
parent 36d1f8a3
...@@ -41,7 +41,6 @@ static u32 acpi_suspend_states[] = { ...@@ -41,7 +41,6 @@ static u32 acpi_suspend_states[] = {
static int acpi_pm_prepare(u32 state) static int acpi_pm_prepare(u32 state)
{ {
int error = 0;
u32 acpi_state = acpi_suspend_states[state]; u32 acpi_state = acpi_suspend_states[state];
if (!sleep_states[acpi_state]) if (!sleep_states[acpi_state])
...@@ -56,15 +55,9 @@ static int acpi_pm_prepare(u32 state) ...@@ -56,15 +55,9 @@ static int acpi_pm_prepare(u32 state)
acpi_set_firmware_waking_vector( acpi_set_firmware_waking_vector(
(acpi_physical_address) acpi_wakeup_address); (acpi_physical_address) acpi_wakeup_address);
} }
ACPI_FLUSH_CPU_CACHE(); ACPI_FLUSH_CPU_CACHE();
acpi_enter_sleep_state_prep(acpi_state); acpi_enter_sleep_state_prep(acpi_state);
return 0; return 0;
Err:
acpi_set_firmware_waking_vector(0);
return error;
} }
...@@ -153,6 +146,20 @@ static int acpi_pm_finish(u32 state) ...@@ -153,6 +146,20 @@ static int acpi_pm_finish(u32 state)
} }
int acpi_suspend(u32 acpi_state)
{
u32 states[] = {
[1] = PM_SUSPEND_STANDBY,
[3] = PM_SUSPEND_MEM,
[4] = PM_SUSPEND_DISK,
};
if (acpi_state <= 4 && states[acpi_state])
return pm_suspend(states[acpi_state]);
return -EINVAL;
}
static struct pm_ops acpi_pm_ops = { static struct pm_ops acpi_pm_ops = {
.prepare = acpi_pm_prepare, .prepare = acpi_pm_prepare,
.enter = acpi_pm_enter, .enter = acpi_pm_enter,
......
...@@ -13,12 +13,71 @@ ...@@ -13,12 +13,71 @@
#include "sleep.h" #include "sleep.h"
#define ACPI_SYSTEM_FILE_SLEEP "sleep"
#define ACPI_SYSTEM_FILE_ALARM "alarm" #define ACPI_SYSTEM_FILE_ALARM "alarm"
#define _COMPONENT ACPI_SYSTEM_COMPONENT #define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME ("sleep") ACPI_MODULE_NAME ("sleep")
static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
{
int i;
ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
for (i = 0; i <= ACPI_STATE_S5; i++) {
if (sleep_states[i]) {
seq_printf(seq,"S%d ", i);
if (i == ACPI_STATE_S4 && acpi_gbl_FACS->S4bios_f)
seq_printf(seq, "S4bios ");
}
}
seq_puts(seq, "\n");
return 0;
}
static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data);
}
static int
acpi_system_write_sleep (
struct file *file,
const char *buffer,
size_t count,
loff_t *ppos)
{
char str[12];
u32 state = 0;
int error = 0;
if (count > sizeof(str) - 1)
goto Done;
memset(str,0,sizeof(str));
if (copy_from_user(str, buffer, count))
return -EFAULT;
/* Check for S4 bios request */
if (!strcmp(str,"4b")) {
error = acpi_suspend(4);
goto Done;
}
state = simple_strtoul(str, NULL, 0);
#ifdef CONFIG_SOFTWARE_SUSPEND
if (state == 4) {
error = software_suspend();
goto Done;
}
#endif
error = acpi_suspend(state);
Done:
return error ? error : count;
}
static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
{ {
u32 sec, min, hr; u32 sec, min, hr;
...@@ -294,6 +353,14 @@ acpi_system_write_alarm ( ...@@ -294,6 +353,14 @@ acpi_system_write_alarm (
} }
static struct file_operations acpi_system_sleep_fops = {
.open = acpi_system_sleep_open_fs,
.read = seq_read,
.write = acpi_system_write_sleep,
.llseek = seq_lseek,
.release = single_release,
};
static struct file_operations acpi_system_alarm_fops = { static struct file_operations acpi_system_alarm_fops = {
.open = acpi_system_alarm_open_fs, .open = acpi_system_alarm_open_fs,
.read = seq_read, .read = seq_read,
...@@ -307,6 +374,12 @@ static int acpi_sleep_proc_init(void) ...@@ -307,6 +374,12 @@ static int acpi_sleep_proc_init(void)
{ {
struct proc_dir_entry *entry = NULL; struct proc_dir_entry *entry = NULL;
/* 'sleep' [R/W]*/
entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP,
S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
if (entry)
entry->proc_fops = &acpi_system_sleep_fops;
/* 'alarm' [R/W] */ /* 'alarm' [R/W] */
entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM, entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM,
S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir); S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
......
extern u8 sleep_states[]; extern u8 sleep_states[];
extern int acpi_suspend (u32 state);
extern acpi_status acpi_suspend (u32 state);
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