PowerOP Take 2 2/3: sysfs UI core

2005-08-24 Thread Todd Poynor
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

2005-08-24 Thread Todd Poynor
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);
+