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;
> +             }
> +     }
>  }

Reply via email to