PowerOP Take 2 2/3: sysfs UI core
A sysfs interface for PowerOP that allows operating points to be created and activated from userspace. The platform-specific backend provides the code to read and write sysfs attributes for each power parameter; the core sysfs interface has no knowledge of the struct powerop_point contents. This interface could be used independently of an integrated cpufreq or DPM interface. It is not an integral part of PowerOP and is provided in part to facilitate discussion and experimentation with PowerOP, but could serve as a basis for a basic userspace power policy management stack. Operating points are created by writing the name of the operating point to /sys/powerop/new. This may be a job for configfs. /sys/powerop// will contain an attribute for each power parameter that may be written to set the associated parameter for the new operating point. An operating point may be activated by writing its name to /sys/powerop/active. The hardware power parameters currently set may be read and written via /sys/powerop/hw/, a special operating point that reads and writes parameter attribute values immediately, primarily for diagnostic purposes. Buried in this interface is also the notion of a registry of "named operating points", allowing operating points created by some other interface (such as cpufreq or loading a module with the definitions as suggested previously by David Brownell) to be activated from userspace via /sys/powerop/active. Changing operating points (or other power-policy-based information that triggers changes in operating points) from userspace is a common scenario in some embedded systems, where power/performance needs change based on system state changes that are coordinated by a userspace process (for example, a mobile phone starting a multimedia application). Index: linux-2.6.13-rc4/drivers/powerop/Kconfig === --- /dev/null +++ linux-2.6.13-rc4/drivers/powerop/Kconfig @@ -0,0 +1,4 @@ +config POWEROP_SYSFS + bool " Enable PowerOP sysfs interface" + depends on POWEROP && SYSFS + help Index: linux-2.6.13-rc4/drivers/powerop/Makefile === --- /dev/null +++ linux-2.6.13-rc4/drivers/powerop/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_POWEROP_SYSFS)+= powerop_sysfs.o Index: linux-2.6.13-rc4/drivers/powerop/powerop_sysfs.c === --- /dev/null +++ linux-2.6.13-rc4/drivers/powerop/powerop_sysfs.c @@ -0,0 +1,398 @@ +/* + * PowerOP sysfs UI + * + * Author: Todd Poynor <[EMAIL PROTECTED]> + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int powerop_register_point(const char *id, struct powerop_point *point); +int powerop_select_point(const char *id); + +struct namedop { + struct kobject kobj; + struct powerop_point *point; + struct list_head node; + struct completion released; +}; + +#define to_namedop(_kobj) container_of(_kobj,\ + struct namedop,kobj) + +static DECLARE_MUTEX(namedop_list_mutex); +static struct list_head namedop_list; +static struct namedop *activeop; + +struct sysfsop { + struct powerop_point point; + struct list_head node; +}; + +static DECLARE_MUTEX(sysfsop_list_mutex); +static struct list_head sysfsop_list; + +static struct powerop_point *hwop; + +#define powerop_attr(_name) \ +static struct subsys_attribute _name##_attr = { \ + .attr = { \ + .name = __stringify(_name), \ + .mode = 0644, \ + .owner = THIS_MODULE, \ + }, \ + .show = _name##_show, \ + .store = _name##_store,\ +} + +static struct attribute_group param_attr_group; + +#define to_powerop_param_attr(_attr) container_of(_attr,\ + struct powerop_param_attribute,attr) + + +decl_subsys(powerop, NULL, NULL); +static int subsys_reg; +static int sysfs_init; + +static void namedop_release(struct kobject *kobj) +{ + struct namedop *op = to_namedop(kobj); + + complete(>released); + return; +} + +static struct sysfsop *sysfsop_create(const char *id) +{ + struct sysfsop *op; + int error; + + if ((op = kmalloc(sizeof(struct sysfsop), GFP_KERNEL)) == NULL) + return ERR_PTR(-ENOMEM); + + down(_list_mutex); + list_add_tail(>node, _list); + up(_list_mutex); + memset(>point, 0, sizeof(struct powerop_point)); + return (error = powerop_register_point(id, >point)) == 0 + ? op : ERR_PTR(error); +}
PowerOP Take 2 2/3: sysfs UI core
A sysfs interface for PowerOP that allows operating points to be created and activated from userspace. The platform-specific backend provides the code to read and write sysfs attributes for each power parameter; the core sysfs interface has no knowledge of the struct powerop_point contents. This interface could be used independently of an integrated cpufreq or DPM interface. It is not an integral part of PowerOP and is provided in part to facilitate discussion and experimentation with PowerOP, but could serve as a basis for a basic userspace power policy management stack. Operating points are created by writing the name of the operating point to /sys/powerop/new. This may be a job for configfs. /sys/powerop/op/ will contain an attribute for each power parameter that may be written to set the associated parameter for the new operating point. An operating point may be activated by writing its name to /sys/powerop/active. The hardware power parameters currently set may be read and written via /sys/powerop/hw/, a special operating point that reads and writes parameter attribute values immediately, primarily for diagnostic purposes. Buried in this interface is also the notion of a registry of named operating points, allowing operating points created by some other interface (such as cpufreq or loading a module with the definitions as suggested previously by David Brownell) to be activated from userspace via /sys/powerop/active. Changing operating points (or other power-policy-based information that triggers changes in operating points) from userspace is a common scenario in some embedded systems, where power/performance needs change based on system state changes that are coordinated by a userspace process (for example, a mobile phone starting a multimedia application). Index: linux-2.6.13-rc4/drivers/powerop/Kconfig === --- /dev/null +++ linux-2.6.13-rc4/drivers/powerop/Kconfig @@ -0,0 +1,4 @@ +config POWEROP_SYSFS + bool Enable PowerOP sysfs interface + depends on POWEROP SYSFS + help Index: linux-2.6.13-rc4/drivers/powerop/Makefile === --- /dev/null +++ linux-2.6.13-rc4/drivers/powerop/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_POWEROP_SYSFS)+= powerop_sysfs.o Index: linux-2.6.13-rc4/drivers/powerop/powerop_sysfs.c === --- /dev/null +++ linux-2.6.13-rc4/drivers/powerop/powerop_sysfs.c @@ -0,0 +1,398 @@ +/* + * PowerOP sysfs UI + * + * Author: Todd Poynor [EMAIL PROTECTED] + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed as is without any warranty of any kind, whether express + * or implied. + */ + +#include linux/config.h +#include linux/module.h +#include linux/powerop_sysfs.h +#include linux/init.h +#include linux/kobject.h +#include linux/list.h +#include linux/slab.h +#include linux/string.h +#include linux/err.h +#include linux/errno.h + +#include asm/powerop.h + +int powerop_register_point(const char *id, struct powerop_point *point); +int powerop_select_point(const char *id); + +struct namedop { + struct kobject kobj; + struct powerop_point *point; + struct list_head node; + struct completion released; +}; + +#define to_namedop(_kobj) container_of(_kobj,\ + struct namedop,kobj) + +static DECLARE_MUTEX(namedop_list_mutex); +static struct list_head namedop_list; +static struct namedop *activeop; + +struct sysfsop { + struct powerop_point point; + struct list_head node; +}; + +static DECLARE_MUTEX(sysfsop_list_mutex); +static struct list_head sysfsop_list; + +static struct powerop_point *hwop; + +#define powerop_attr(_name) \ +static struct subsys_attribute _name##_attr = { \ + .attr = { \ + .name = __stringify(_name), \ + .mode = 0644, \ + .owner = THIS_MODULE, \ + }, \ + .show = _name##_show, \ + .store = _name##_store,\ +} + +static struct attribute_group param_attr_group; + +#define to_powerop_param_attr(_attr) container_of(_attr,\ + struct powerop_param_attribute,attr) + + +decl_subsys(powerop, NULL, NULL); +static int subsys_reg; +static int sysfs_init; + +static void namedop_release(struct kobject *kobj) +{ + struct namedop *op = to_namedop(kobj); + + complete(op-released); + return; +} + +static struct sysfsop *sysfsop_create(const char *id) +{ + struct sysfsop *op; + int error; + + if ((op = kmalloc(sizeof(struct sysfsop), GFP_KERNEL)) == NULL) + return ERR_PTR(-ENOMEM); + + down(sysfsop_list_mutex); + list_add_tail(op-node, sysfsop_list); +