My x220 never generates an event when the LID opens.  So after
suspending by closing the lid the corresponding sensors will always
report a closed lid:

$ sysctl hw.sensors.acpibtn0
hw.sensors.acpibtn0.indicator0=Off (lid open)

This confuses programs like upowerd(8) used at least by GNOME which then
decides to deactivate my screen when an external monitor is plugged in.

Diff below fixes that by adding a resume hook to acpibtn(4) in order to
re-evaluate the "_LID" status of the node.

ok?

Index: acpibtn.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpibtn.c,v
retrieving revision 1.41
diff -u -p -r1.41 acpibtn.c
--- acpibtn.c   27 Jan 2015 19:40:14 -0000      1.41
+++ acpibtn.c   6 Jan 2016 08:55:15 -0000
@@ -35,6 +35,7 @@
 int    acpibtn_match(struct device *, void *, void *);
 void   acpibtn_attach(struct device *, struct device *, void *);
 int    acpibtn_notify(struct aml_node *, int, void *);
+int    acpibtn_activate(struct device *, int);
 
 struct acpibtn_softc {
        struct device           sc_dev;
@@ -65,7 +66,8 @@ SLIST_HEAD(acpi_lid_head, acpi_lid) acpi
     SLIST_HEAD_INITIALIZER(acpibtn_lids);
 
 struct cfattach acpibtn_ca = {
-       sizeof(struct acpibtn_softc), acpibtn_match, acpibtn_attach
+       sizeof(struct acpibtn_softc), acpibtn_match, acpibtn_attach, NULL,
+       acpibtn_activate
 };
 
 struct cfdriver acpibtn_cd = {
@@ -155,7 +157,7 @@ acpibtn_attach(struct device *parent, st
        struct acpibtn_softc    *sc = (struct acpibtn_softc *)self;
        struct acpi_attach_args *aa = aux;
        struct acpi_lid         *lid;
-       int64_t                 lid_open;
+       int64_t                 lid_open = 1;
        int64_t                 st;
 
        sc->sc_acpi = (struct acpi_softc *)parent;
@@ -258,5 +260,25 @@ sleep:
                break;
        }
 
+       return (0);
+}
+
+int
+acpibtn_activate(struct device *self, int act)
+{
+       struct acpibtn_softc    *sc = (struct acpibtn_softc *)self;
+       int64_t                 lid_open = 1;
+
+       switch (act) {
+       case DVACT_WAKEUP:
+               switch (sc->sc_btn_type) {
+               case ACPIBTN_LID:
+                       aml_evalinteger(sc->sc_acpi, sc->sc_devnode,
+                           "_LID", 0, NULL, &lid_open);
+                       sc->sc_sens.value = lid_open;
+                       break;
+               }
+               break;
+       }
        return (0);
 }

Reply via email to