Very strange...

I'm still investigating the issue and glancing at your acpidump.
I'll send a tracing diff your way soon because I'm curious what the
AML path is inside _TMP once your machine resumes.

Until then I wanted to ask you if you're also testing with the glk diff
when you're testing my acpiec_clear_events diff?

You should have the following in /sys/dev/acpi:


Index: dsdt.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.205
diff -u -p -r1.205 dsdt.c
--- dsdt.c      12 Dec 2013 20:56:01 -0000      1.205
+++ dsdt.c      12 Apr 2014 10:45:02 -0000
@@ -736,72 +736,58 @@ static long global_lock_count = 0;
 void
 acpi_glk_enter(void)
 {
-       acpi_acquire_glk(&acpi_softc->sc_facs->global_lock);
-}
-
-void
-acpi_glk_leave(void)
-{
-       int x;
-
-       if (acpi_release_glk(&acpi_softc->sc_facs->global_lock)) {
-               /*
-                * If pending, notify the BIOS that the lock was released
-                * by the OSPM. No locking is needed because nobody outside
-                * the ACPI thread is touching this register.
-                */
-               x = acpi_read_pmreg(acpi_softc, ACPIREG_PM1_CNT, 0);
-               x |= ACPI_PM1_GBL_RLS;
-               acpi_write_pmreg(acpi_softc, ACPIREG_PM1_CNT, 0, x);
-       }
-}
-
-void
-aml_lockfield(struct aml_scope *scope, struct aml_value *field)
-{
        int st = 0;
 
-       if (AML_FIELD_LOCK(field->v_field.flags) != AML_FIELD_LOCK_ON)
-               return;
-
-       /* If lock is already ours, just continue */
+       /* If lock is already ours, just continue. */
        if (global_lock_count++)
                return;
 
-       /* Spin to acquire lock */
+       /* Spin to acquire the lock. */
        while (!st) {
                st = acpi_acquire_glk(&acpi_softc->sc_facs->global_lock);
                /* XXX - yield/delay? */
        }
-
-       return;
 }
 
 void
-aml_unlockfield(struct aml_scope *scope, struct aml_value *field)
+acpi_glk_leave(void)
 {
-       int st, x, s;
+       int st, x;
 
-       if (AML_FIELD_LOCK(field->v_field.flags) != AML_FIELD_LOCK_ON)
-               return;
-
-       /* If we are the last ones, turn out the lights */
+       /* If we are the last one, turn out the lights. */
        if (--global_lock_count)
                return;
 
-       /* Release lock */
        st = acpi_release_glk(&acpi_softc->sc_facs->global_lock);
        if (!st)
                return;
 
-       /* Signal others if someone waiting */
-       s = spltty();
+       /*
+        * If pending, notify the BIOS that the lock was released by
+        * OSPM.  No locking is needed because nobody outside the ACPI
+        * thread is supposed to touch this register.
+        */
        x = acpi_read_pmreg(acpi_softc, ACPIREG_PM1_CNT, 0);
        x |= ACPI_PM1_GBL_RLS;
        acpi_write_pmreg(acpi_softc, ACPIREG_PM1_CNT, 0, x);
-       splx(s);
+}
+
+void
+aml_lockfield(struct aml_scope *scope, struct aml_value *field)
+{
+       if (AML_FIELD_LOCK(field->v_field.flags) != AML_FIELD_LOCK_ON)
+               return;
+
+       acpi_glk_enter();
+}
+
+void
+aml_unlockfield(struct aml_scope *scope, struct aml_value *field)
+{
+       if (AML_FIELD_LOCK(field->v_field.flags) != AML_FIELD_LOCK_ON)
+               return;
 
-       return;
+       acpi_glk_leave();
 }
 
 /*
Index: acpiec.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpiec.c,v
retrieving revision 1.48
diff -u -p -r1.48 acpiec.c
--- acpiec.c    2 Jul 2013 18:37:47 -0000       1.48
+++ acpiec.c    12 Apr 2014 10:45:03 -0000
@@ -34,6 +34,7 @@
 
 int            acpiec_match(struct device *, void *, void *);
 void           acpiec_attach(struct device *, struct device *, void *);
+int            acpiec_activate(struct device *, int);
 
 u_int8_t       acpiec_status(struct acpiec_softc *);
 u_int8_t       acpiec_read_data(struct acpiec_softc *);
@@ -54,6 +55,7 @@ int           acpiec_getregister(const u_int8_t *
 
 void           acpiec_wait(struct acpiec_softc *, u_int8_t, u_int8_t);
 void           acpiec_sci_event(struct acpiec_softc *);
+void           acpiec_clear_events(struct acpiec_softc *);
 
 void           acpiec_get_events(struct acpiec_softc *);
 
@@ -82,7 +84,8 @@ void          acpiec_unlock(struct acpiec_softc 
 int    acpiec_reg(struct acpiec_softc *);
 
 struct cfattach acpiec_ca = {
-       sizeof(struct acpiec_softc), acpiec_match, acpiec_attach
+       sizeof(struct acpiec_softc), acpiec_match, acpiec_attach,
+       NULL, acpiec_activate
 };
 
 struct cfdriver acpiec_cd = {
@@ -296,6 +299,8 @@ acpiec_attach(struct device *parent, str
        acpi_set_gpehandler(sc->sc_acpi, sc->sc_gpe, acpiec_gpehandler,
            sc, 1);
 #endif
+
+       acpiec_clear_events(sc);
        
        if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_GLK", 0, NULL, &res))
                sc->sc_glk = 0;
@@ -307,6 +312,20 @@ acpiec_attach(struct device *parent, str
        printf("\n");
 }
 
+int
+acpiec_activate(struct device *self, int act)
+{
+       struct acpiec_softc *sc = (struct acpiec_softc *)self;
+
+
+       switch (act) {
+       case DVACT_RESUME:
+               acpiec_clear_events(sc);
+               break;
+       }
+       return (0);
+}
+
 void
 acpiec_get_events(struct acpiec_softc *sc)
 {
@@ -552,4 +571,18 @@ acpiec_unlock(struct acpiec_softc *sc)
        }
 
        sc->sc_ecbusy = 0;
+}
+
+void
+acpiec_clear_events(struct acpiec_softc *sc)
+{
+       int i;
+
+       for (i = 0; i < 100; i++) {
+               acpiec_write_cmd(sc, EC_CMD_QR);
+               sc->sc_gotsci = 0;
+               if ((acpiec_status(sc) & EC_STAT_SCI_EVT) != EC_STAT_SCI_EVT) {
+                       break;
+               }
+       }
 }

Reply via email to