reads from /dev/acpievent return acpi events. currently the only available event is power. the purpose of this is so power button -> acpi event -> fshalt -> off Reference: /n/atom/patch/applied2013/acpieventq Date: Tue Oct 22 10:22:24 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/nix/k10/devacpi.c Tue Oct 22 10:21:30 2013 +++ /sys/src/nix/k10/devacpi.c Tue Oct 22 10:21:31 2013 @@ -19,6 +19,9 @@ Lock; int init; void (*powerbutton)(void); + + u32int eventopen; + Queue *event; }; /* internal */ @@ -58,7 +61,7 @@ static Dirtab acpidir[]={ ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, "acpictl", {Qctl}, 0, 0666, - "acpievent", {Qevent}, 0, 0444, + "acpievent", {Qevent, 0, QTEXCL}, 0, DMEXCL|0440, }; static Gpe* gpes; /* General purpose events */ @@ -286,6 +289,7 @@ { int i; uint sts, en; + Queue *q; for(i = 0; i < ngpe; i++) if(getgpests(i)){ @@ -305,8 +309,9 @@ } setpm1sts(sts); if(sts&Epowerbtn){ - aconf.powerbutton(); - // qiwrite(event.q, "power"); + if((q = aconf.event) == nil + || qiwrite(q, "powerbutton\n", 12) == -1) + aconf.powerbutton(); } } @@ -418,12 +423,38 @@ static Chan* acpiopen(Chan *c, int omode) { - return devopen(c, omode, acpidir, nelem(acpidir), acpigen); + c = devopen(c, omode, acpidir, nelem(acpidir), acpigen); + switch((uint)c->qid.path){ + case Qevent: + if(tas32(&aconf.eventopen) != 0){ + c->flag &= ~COPEN; + error(Einuse); + } + if(aconf.event == nil){ + aconf.event = qopen(8*1024, Qmsg, 0, 0); + if(aconf.event == nil){ + c->flag &= ~COPEN; + error(Enomem); + } + qnoblock(aconf.event, 1); + }else + qreopen(aconf.event); + break; + } + return c; } static void -acpiclose(Chan *) +acpiclose(Chan *c) { + switch((uint)c->qid.path){ + case Qevent: + if(c->flag & COPEN){ + aconf.eventopen = 0; + qhangup(aconf.event, nil); + } + break; + } } static long @@ -453,8 +484,7 @@ return readstr(off, a, n, buf); case Qevent: - s = ""; - return readstr(off, a, n, s); + return qread(aconf.event, a, n); } error(Eperm); return -1;