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 <[EMAIL PROTECTED]>
---
 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 <[EMAIL PROTECTED]>
_______________________________________________
Devel mailing list
Devel@lists.laptop.org
http://lists.laptop.org/listinfo/devel

Reply via email to