On Wed, Nov 29, 2017 at 11:31:18PM +0100, Mark Kettenis wrote:
> Diff below adds support for ACPI GPIO-signaled events to the
> chvgpio(4) driver.  This makes the laptop I have here realize the lid
> is closed or opened.
> 
> ok?
> 

ok mlarkin

-ml
> 
> Index: dev/acpi/acpi.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
> retrieving revision 1.334
> diff -u -p -r1.334 acpi.c
> --- dev/acpi/acpi.c   16 Nov 2017 18:12:27 -0000      1.334
> +++ dev/acpi/acpi.c   29 Nov 2017 22:16:52 -0000
> @@ -834,6 +834,87 @@ acpi_pciroots_attach(struct device *dev,
>       }
>  }
>  
> +/* GPIO support */
> +
> +struct acpi_gpio_event {
> +     struct aml_node *node;
> +     int pin;
> +};
> +
> +void
> +acpi_gpio_event_task(void *arg0, int arg1)
> +{
> +     struct aml_node *node = arg0;
> +     int pin = arg1;
> +     char name[5];
> +
> +     snprintf(name, sizeof(name), "_E%.2X", pin);
> +     aml_evalname(acpi_softc, node, name, 0, NULL, NULL);
> +}
> +
> +int
> +acpi_gpio_event(void *arg)
> +{
> +     struct acpi_gpio_event *ev = arg;
> +
> +     acpi_addtask(acpi_softc, acpi_gpio_event_task, ev->node, ev->pin);
> +     return 1;
> +}
> +
> +int
> +acpi_gpio_parse_events(int crsidx, union acpi_resource *crs, void *arg)
> +{
> +     struct aml_node *devnode = arg;
> +     struct aml_node *node;
> +     uint16_t pin;
> +
> +     switch (AML_CRSTYPE(crs)) {
> +     case LR_GPIO:
> +             node = aml_searchname(devnode,
> +                 (char *)&crs->pad[crs->lr_gpio.res_off]);
> +             pin = *(uint16_t *)&crs->pad[crs->lr_gpio.pin_off];
> +             if (crs->lr_gpio.type == LR_GPIO_INT && node && node->gpio) {
> +                     struct acpi_gpio *gpio = node->gpio;
> +                     struct acpi_gpio_event *ev;
> +
> +                     ev = malloc(sizeof(*ev), M_DEVBUF, M_WAITOK);
> +                     ev->node = devnode;
> +                     ev->pin = pin;
> +                     gpio->intr_establish(gpio->cookie, pin,
> +                         crs->lr_gpio.tflags, acpi_gpio_event, ev);
> +             }
> +             break;
> +     default:
> +             printf("%s: unknown resource type %d\n", __func__,
> +                 AML_CRSTYPE(crs));
> +     }
> +
> +     return 0;
> +}
> +
> +void
> +acpi_register_gpio(struct acpi_softc *sc, struct aml_node *devnode)
> +{
> +     struct aml_value arg[2];
> +     struct aml_node *node;
> +     struct aml_value res;
> +
> +     /* Register GeneralPurposeIO address space. */
> +     memset(&arg, 0, sizeof(arg));
> +     arg[0].type = AML_OBJTYPE_INTEGER;
> +     arg[0].v_integer = ACPI_OPREG_GPIO;
> +     arg[1].type = AML_OBJTYPE_INTEGER;
> +     arg[1].v_integer = 1;
> +     node = aml_searchname(devnode, "_REG");
> +     if (node && aml_evalnode(sc, node, 2, arg, NULL))
> +             printf("%s: _REG failed\n", node->name);
> +
> +     /* Register GPIO signaled ACPI events. */
> +     if (aml_evalname(sc, devnode, "_AEI", 0, NULL, &res))
> +             return;
> +     aml_parse_resource(&res, acpi_gpio_parse_events, devnode);
> +}
> +
>  void
>  acpi_attach(struct device *parent, struct device *self, void *aux)
>  {
> Index: dev/acpi/acpivar.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
> retrieving revision 1.88
> diff -u -p -r1.88 acpivar.h
> --- dev/acpi/acpivar.h        17 Aug 2017 05:16:27 -0000      1.88
> +++ dev/acpi/acpivar.h        29 Nov 2017 22:15:32 -0000
> @@ -332,6 +332,8 @@ void acpi_wakeup(void *);
>  
>  int acpi_gasio(struct acpi_softc *, int, int, uint64_t, int, int, void *);
>  
> +void acpi_register_gpio(struct acpi_softc *, struct aml_node *);
> +
>  int  acpi_set_gpehandler(struct acpi_softc *, int,
>           int (*)(struct acpi_softc *, int, void *), void *, int);
>  void acpi_enable_gpe(struct acpi_softc *, u_int32_t);
> Index: dev/acpi/chvgpio.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/chvgpio.c,v
> retrieving revision 1.7
> diff -u -p -r1.7 chvgpio.c
> --- dev/acpi/chvgpio.c        29 Nov 2017 15:22:22 -0000      1.7
> +++ dev/acpi/chvgpio.c        29 Nov 2017 22:15:13 -0000
> @@ -169,8 +169,6 @@ chvgpio_attach(struct device *parent, st
>       struct acpi_attach_args *aaa = aux;
>       struct chvgpio_softc *sc = (struct chvgpio_softc *)self;
>       struct aml_value res;
> -     struct aml_value arg[2];
> -     struct aml_node *node;
>       int64_t uid;
>       int i;
>  
> @@ -251,19 +249,11 @@ chvgpio_attach(struct device *parent, st
>  
>       printf(", %d pins\n", sc->sc_npins);
>  
> -     /* Register GeneralPurposeIO address space. */
> -     memset(&arg, 0, sizeof(arg));
> -     arg[0].type = AML_OBJTYPE_INTEGER;
> -     arg[0].v_integer = ACPI_OPREG_GPIO;
> -     arg[1].type = AML_OBJTYPE_INTEGER;
> -     arg[1].v_integer = 1;
> -     node = aml_searchname(sc->sc_node, "_REG");
> -     if (node && aml_evalnode(sc->sc_acpi, node, 2, arg, NULL))
> -             printf("%s: _REG failed\n", sc->sc_dev.dv_xname);
> -
>       /* Register OEM defined address space. */
>       aml_register_regionspace(sc->sc_node, CHVGPIO_REGIONSPACE_BASE + uid,
>           sc, chvgpio_opreg_handler);
> +
> +     acpi_register_gpio(sc->sc_acpi, sc->sc_node);
>       return;
>  
>  unmap:
> 

Reply via email to