On Sat, Apr 12, 2014 at 01:47:15PM +0300, Paul Irofti wrote: > 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?
I applied the previous patch to a fresh checked out source tree which didn't contain below changes. Should I have applied several patches together? Applying this patch to a freshly checked out source tree results in the same behaviour as with last tests: the system shuts down right after boot because of wrong temperator for acpitz0 and sometimes it's getting it right. Ususally battery data is absent or only partly there. > 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; > + } > + } > }