Commit fcab304b authored by Patrick Mochel's avatar Patrick Mochel

[power] Register PM subsystem, and create power/ directory in sysfs.

- Add file 'state' which provides single point of entry for all PM 
  transitions.
  File accepts a string specifying what state to enter, which is one of:
  "standby": Power-on Suspend (aka S1)
  "suspend": Suspend-to-RAM (aka S3)
  "hibernate": Suspend-to-disk (aka S4)

  The names do suck, because they are lifted from the ACPI spec. Better 
  naming suggestions are welcome, though these names are relatively well-
  known. 

- Handler for file does little now, but will validate the passed string and
  call the appropriate functions. 

- Needs to be integrated with swsusp and ACPI S3 code.
parent bee60089
obj-y := process.o console.o pm.o
obj-y := main.o process.o console.o pm.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o
/*
* kernel/power/main.c - PM subsystem core functionality.
*
* Copyright (c) 2003 Patrick Mochel
* Copyright (c) 2003 Open Source Development Lab
*
* This file is release under the GPLv2
*
*/
#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/pm.h>
static int standby(void)
{
return 0;
}
static int suspend(void)
{
return 0;
}
static int hibernate(void)
{
return 0;
}
#define decl_state(_name) \
{ .name = __stringify(_name), .fn = _name }
struct pm_state {
char * name;
int (*fn)(void);
} pm_states[] = {
decl_state(standby),
decl_state(suspend),
decl_state(hibernate),
{ NULL },
};
static int enter_state(struct pm_state * state)
{
return state->fn();
}
decl_subsys(power,NULL,NULL);
#define power_attr(_name) \
static struct subsys_attribute _name##_attr = { \
.attr = { \
.name = __stringify(_name), \
.mode = 0644, \
}, \
.show = _name##_show, \
.store = _name##_store, \
}
/**
* state - control system power state.
*
* show() returns what states are supported, which is hard-coded to
* 'standby' (Power-On Suspend), 'suspend' (Suspend-to-RAM), and
* 'hibernate' (Suspend-to-Disk).
*
* store() accepts one of those strings, translates it into the
* proper enumerated value, and initiates a suspend transition.
*/
static ssize_t state_show(struct subsystem * subsys, char * buf)
{
struct pm_state * state;
char * s = buf;
for (state = &pm_states[0]; state->name; state++)
s += sprintf(s,"%s ",state->name);
s += sprintf(s,"\n");
return (s - buf);
}
static ssize_t state_store(struct subsystem * s, const char * buf, size_t n)
{
struct pm_state * state;
int error;
char * end = strchr(buf,'\n');
if (end)
*end = '\0';
for (state = &pm_states[0]; state; state++) {
if (!strcmp(buf,state->name))
break;
}
if (!state)
return -EINVAL;
error = enter_state(state);
return error ? error : n;
}
power_attr(state);
static struct attribute * g[] = {
&state_attr.attr,
NULL,
};
static struct attribute_group attr_group = {
.attrs = g,
};
static int pm_init(void)
{
int error = subsystem_register(&power_subsys);
if (!error)
error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group);
return error;
}
core_initcall(pm_init);
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