Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 292775
b: refs/heads/master
c: d1f42e3
h: refs/heads/master
i:
  292773: e17bf74
  292771: b31f6e3
  292767: 952bfa2
v: v3
  • Loading branch information
Daniel Drake authored and Ingo Molnar committed Mar 6, 2012
1 parent 4bce07b commit b7e4378
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: da4e3302949f4a702f1ddfefe067762232d363d5
refs/heads/master: d1f42e314c9c50541c79a6edf2b4cab63fe02ee3
72 changes: 71 additions & 1 deletion trunk/arch/x86/platform/olpc/olpc-xo15-sci.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,66 @@
#define XO15_SCI_CLASS DRV_NAME
#define XO15_SCI_DEVICE_NAME "OLPC XO-1.5 SCI"

static unsigned long xo15_sci_gpe;
static unsigned long xo15_sci_gpe;
static bool lid_wake_on_close;

/*
* The normal ACPI LID wakeup behavior is wake-on-open, but not
* wake-on-close. This is implemented as standard by the XO-1.5 DSDT.
*
* We provide here a sysfs attribute that will additionally enable
* wake-on-close behavior. This is useful (e.g.) when we oportunistically
* suspend with the display running; if the lid is then closed, we want to
* wake up to turn the display off.
*
* This is controlled through a custom method in the XO-1.5 DSDT.
*/
static int set_lid_wake_behavior(bool wake_on_close)
{
struct acpi_object_list arg_list;
union acpi_object arg;
acpi_status status;

arg_list.count = 1;
arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = wake_on_close;

status = acpi_evaluate_object(NULL, "\\_SB.PCI0.LID.LIDW", &arg_list, NULL);
if (ACPI_FAILURE(status)) {
pr_warning(PFX "failed to set lid behavior\n");
return 1;
}

lid_wake_on_close = wake_on_close;

return 0;
}

static ssize_t
lid_wake_on_close_show(struct kobject *s, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", lid_wake_on_close);
}

static ssize_t lid_wake_on_close_store(struct kobject *s,
struct kobj_attribute *attr,
const char *buf, size_t n)
{
unsigned int val;

if (sscanf(buf, "%u", &val) != 1)
return -EINVAL;

set_lid_wake_behavior(!!val);

return n;
}

static struct kobj_attribute lid_wake_on_close_attr =
__ATTR(lid_wake_on_close, 0644,
lid_wake_on_close_show,
lid_wake_on_close_store);

static void battery_status_changed(void)
{
Expand Down Expand Up @@ -91,6 +150,7 @@ static int xo15_sci_add(struct acpi_device *device)
{
unsigned long long tmp;
acpi_status status;
int r;

if (!device)
return -EINVAL;
Expand All @@ -112,6 +172,10 @@ static int xo15_sci_add(struct acpi_device *device)

dev_info(&device->dev, "Initialized, GPE = 0x%lx\n", xo15_sci_gpe);

r = sysfs_create_file(&device->dev.kobj, &lid_wake_on_close_attr.attr);
if (r)
goto err_sysfs;

/* Flush queue, and enable all SCI events */
process_sci_queue();
olpc_ec_mask_write(EC_SCI_SRC_ALL);
Expand All @@ -123,13 +187,19 @@ static int xo15_sci_add(struct acpi_device *device)
device_init_wakeup(&device->dev, true);

return 0;

err_sysfs:
acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
cancel_work_sync(&sci_work);
return r;
}

static int xo15_sci_remove(struct acpi_device *device, int type)
{
acpi_disable_gpe(NULL, xo15_sci_gpe);
acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
cancel_work_sync(&sci_work);
sysfs_remove_file(&device->dev.kobj, &lid_wake_on_close_attr.attr);
return 0;
}

Expand Down

0 comments on commit b7e4378

Please sign in to comment.