[PATCH #6010] Add sysfs interface to enable/disable wakeup events

Deepak Saxena dsaxena at laptop.org
Fri Jun 13 17:43:05 EDT 2008


Chris,

Here's the initial patch (vs testing kernel) for #6010 to provide an 
interface that OHM can use to enable/disable wakeup events. It still
needs error handling for the ec_cmd() calls but other than that it is
ready to be tested.

Tnx,
~Deepak

--

Expose OLPC EC wakeup event mask to user space via sysfs files
in /sys/power/wakeup_events, with one file per event type. 

Signed-off-by: Deepak Saxena <dsaxena at laptop.org>
---
 arch/x86/kernel/olpc-pm.c |   67 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/olpc-pm.c b/arch/x86/kernel/olpc-pm.c
index e99a464..7e5c0ff 100644
--- a/arch/x86/kernel/olpc-pm.c
+++ b/arch/x86/kernel/olpc-pm.c
@@ -681,6 +681,72 @@ static struct attribute_group olpc_attrs = {
 	.attrs = olpc_attributes,
 };
 
+static ssize_t wackup_event_show(struct kobject *s, struct kobj_attribute *attr, char *buf);
+static ssize_t wackup_event_store(struct kobject *s, struct kobj_attribute *attr, const char *buf, size_t n);
+
+static struct kobj_attribute wackup_event_attr[] = {
+	__ATTR(gamekey, 0600, wackup_event_show, wackup_event_store),
+	__ATTR(battery_state, 0600, wackup_event_show, wackup_event_store),
+	__ATTR(battery_soc, 0600, wackup_event_show, wackup_event_store),
+	__ATTR(battery_error, 0600, wackup_event_show, wackup_event_store),
+	__ATTR(ebook_mode_change, 0600, wackup_event_show, wackup_event_store),
+	__ATTR(wlan, 0600, wackup_event_show, wackup_event_store),
+	__ATTR(ac_power, 0600, wackup_event_show, wackup_event_store),
+};
+
+static DEFINE_RWLOCK(wackup_event_lock);
+
+static ssize_t wackup_event_show(struct kobject *s, struct kobj_attribute *attr, char *buf) 
+{
+	u8 data;
+	unsigned char shift = attr - wackup_event_attr;
+
+	read_lock(&wackup_event_lock);
+	olpc_ec_cmd(EC_READ_SCI_MASK, NULL, 0, &data, 1);
+	read_unlock(&wackup_event_lock);
+
+	return sprintf(buf, "%d\n", (data >> shift) & 1);
+}
+
+static ssize_t wackup_event_store(struct kobject *s, struct kobj_attribute *attr, const char *buf, size_t n)
+{
+	u8 data;
+	unsigned enabled;
+	unsigned char shift = attr - wackup_event_attr;
+
+	if (sscanf(buf, "%d\n", &enabled) != 1)
+		return -EINVAL;
+
+	write_lock(&wackup_event_lock);
+	olpc_ec_cmd(EC_READ_SCI_MASK, NULL, 0, &data, 1);
+
+	if (enabled)
+		data |= 1 << shift;
+	else
+		data &= ~(1 << shift);
+
+	olpc_ec_cmd(EC_WRITE_SCI_MASK, &data, 1, NULL, 0);
+	write_unlock(&wackup_event_lock);
+
+	return n;
+}
+
+static struct attribute * olpc_wackup_event_attributes[] = {
+	&wackup_event_attr[0].attr,
+	&wackup_event_attr[1].attr,
+	&wackup_event_attr[2].attr,
+	&wackup_event_attr[3].attr,
+	&wackup_event_attr[4].attr,
+	&wackup_event_attr[5].attr,
+	&wackup_event_attr[6].attr,
+	NULL
+};
+
+static struct attribute_group olpc_wackup_event_attrs = {
+	.attrs	= olpc_wackup_event_attributes,
+	.name	= "wakeup_events"
+};
+
 static int __init alloc_inputdevs(void)
 {
 	int ret = -ENOMEM;
@@ -848,6 +914,7 @@ static int __init olpc_pm_init(void)
 	suspend_set_ops(&olpc_pm_ops);
 
 	sysfs_create_group(power_kobj, &olpc_attrs);
+ 	sysfs_create_group(power_kobj, &olpc_wackup_event_attrs);
 
 	return 0;
 }

-- 
Deepak Saxena <dsaxena at laptop.org>



More information about the Devel mailing list