Module Name: src Committed By: jmcneill Date: Mon Dec 9 22:10:25 UTC 2024
Modified Files: src/sys/dev/acpi: acpi_gpio.c acpi_gpio.h acpivar.h qcomgpio.c qcomgpioreg.h Log Message: acpi: gpio: Pass the full ACPI_RESOURCE_GPIO to the translate callback. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/dev/acpi/acpi_gpio.c \ src/sys/dev/acpi/acpi_gpio.h src/sys/dev/acpi/qcomgpio.c \ src/sys/dev/acpi/qcomgpioreg.h cvs rdiff -u -r1.91 -r1.92 src/sys/dev/acpi/acpivar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/acpi/acpi_gpio.c diff -u src/sys/dev/acpi/acpi_gpio.c:1.1 src/sys/dev/acpi/acpi_gpio.c:1.2 --- src/sys/dev/acpi/acpi_gpio.c:1.1 Sun Dec 8 20:49:14 2024 +++ src/sys/dev/acpi/acpi_gpio.c Mon Dec 9 22:10:25 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_gpio.c,v 1.1 2024/12/08 20:49:14 jmcneill Exp $ */ +/* $NetBSD: acpi_gpio.c,v 1.2 2024/12/09 22:10:25 jmcneill Exp $ */ /*- * Copyright (c) 2024 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_gpio.c,v 1.1 2024/12/08 20:49:14 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_gpio.c,v 1.2 2024/12/09 22:10:25 jmcneill Exp $"); #include <sys/param.h> #include <sys/gpio.h> @@ -45,7 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_gpio.c, int acpi_gpio_register(struct acpi_devnode *ad, device_t dev, - int (*translate)(void *, ACPI_INTEGER, void **), void *priv) + int (*translate)(void *, ACPI_RESOURCE_GPIO *, void **), void *priv) { if (ad->ad_gpiodev != NULL) { device_printf(dev, "%s already registered\n", @@ -95,7 +95,7 @@ acpi_gpio_translate(ACPI_RESOURCE_GPIO * } xpin = gpioad->ad_gpio_translate(gpioad->ad_gpio_priv, - res->PinTable[0], gpiop); + res, gpiop); if (xpin == -1) { /* Pin could not be translated. */ return AE_NOT_IMPLEMENTED; @@ -148,15 +148,15 @@ acpi_gpio_get_int(ACPI_HANDLE hdl, u_int if (ACPI_FAILURE(rv)) { return rv; } + gpio = ctx.res; - rv = acpi_gpio_translate(ctx.res, gpiop, pin); + rv = acpi_gpio_translate(gpio, gpiop, pin); if (ACPI_FAILURE(rv)) { printf("%s: translate failed: %s\n", __func__, AcpiFormatException(rv)); return rv; } - gpio = ctx.res; if (gpio->Triggering == ACPI_LEVEL_SENSITIVE) { *irqmode = gpio->Polarity == ACPI_ACTIVE_HIGH ? GPIO_INTR_HIGH_LEVEL : GPIO_INTR_LOW_LEVEL; @@ -176,7 +176,7 @@ acpi_gpio_get_int(ACPI_HANDLE hdl, u_int } ACPI_STATUS -acpi_gpio_get_io(ACPI_HANDLE hdl, u_int index, void **gpio, int *pin) +acpi_gpio_get_io(ACPI_HANDLE hdl, u_int index, void **gpiop, int *pin) { struct acpi_gpio_resource_context ctx = { .index = index, @@ -189,5 +189,5 @@ acpi_gpio_get_io(ACPI_HANDLE hdl, u_int return rv; } - return acpi_gpio_translate(ctx.res, gpio, pin); + return acpi_gpio_translate(ctx.res, gpiop, pin); } Index: src/sys/dev/acpi/acpi_gpio.h diff -u src/sys/dev/acpi/acpi_gpio.h:1.1 src/sys/dev/acpi/acpi_gpio.h:1.2 --- src/sys/dev/acpi/acpi_gpio.h:1.1 Sun Dec 8 20:49:14 2024 +++ src/sys/dev/acpi/acpi_gpio.h Mon Dec 9 22:10:25 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_gpio.h,v 1.1 2024/12/08 20:49:14 jmcneill Exp $ */ +/* $NetBSD: acpi_gpio.h,v 1.2 2024/12/09 22:10:25 jmcneill Exp $ */ /*- * Copyright (c) 2024 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #define _DEV_ACPI_ACPI_GPIO_H int acpi_gpio_register(struct acpi_devnode *, device_t, - int (*)(void *, ACPI_INTEGER, void **), void *); + int (*)(void *, ACPI_RESOURCE_GPIO *, void **), void *); ACPI_STATUS acpi_gpio_get_int(ACPI_HANDLE, u_int, void **, int *, int *); ACPI_STATUS acpi_gpio_get_io(ACPI_HANDLE, u_int, void **, int *); Index: src/sys/dev/acpi/qcomgpio.c diff -u src/sys/dev/acpi/qcomgpio.c:1.1 src/sys/dev/acpi/qcomgpio.c:1.2 --- src/sys/dev/acpi/qcomgpio.c:1.1 Sun Dec 8 20:49:14 2024 +++ src/sys/dev/acpi/qcomgpio.c Mon Dec 9 22:10:25 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: qcomgpio.c,v 1.1 2024/12/08 20:49:14 jmcneill Exp $ */ +/* $NetBSD: qcomgpio.c,v 1.2 2024/12/09 22:10:25 jmcneill Exp $ */ /*- * Copyright (c) 2024 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: qcomgpio.c,v 1.1 2024/12/08 20:49:14 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: qcomgpio.c,v 1.2 2024/12/09 22:10:25 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -56,13 +56,14 @@ typedef enum { struct qcomgpio_config { u_int num_pins; - int (*translate)(ACPI_INTEGER); + int (*translate)(ACPI_RESOURCE_GPIO *); }; struct qcomgpio_intr_handler { int (*ih_func)(void *); void *ih_arg; int ih_pin; + int ih_type; LIST_ENTRY(qcomgpio_intr_handler) ih_list; }; @@ -96,7 +97,7 @@ static bool qcomgpio_intr_str(void *, in static void qcomgpio_intr_mask(void *, void *); static void qcomgpio_intr_unmask(void *, void *); -static int qcomgpio_acpi_translate(void *, ACPI_INTEGER, void **); +static int qcomgpio_acpi_translate(void *, ACPI_RESOURCE_GPIO *, void **); static void qcomgpio_register_event(void *, struct acpi_event *, ACPI_RESOURCE_GPIO *); static int qcomgpio_intr(void *); @@ -104,12 +105,18 @@ static int qcomgpio_intr(void *); CFATTACH_DECL_NEW(qcomgpio, sizeof(struct qcomgpio_softc), qcomgpio_match, qcomgpio_attach, NULL, NULL); +#define X1E_NUM_PINS 239 + static int -qcomgpio_x1e_translate(ACPI_INTEGER val) +qcomgpio_x1e_translate(ACPI_RESOURCE_GPIO *gpio) { - switch (val) { - case 0x33: - return 51; + const ACPI_INTEGER pin = gpio->PinTable[0]; + + if (pin < X1E_NUM_PINS) { + return gpio->PinTable[0]; + } + + switch (pin) { case 0x180: return 67; case 0x380: @@ -120,7 +127,7 @@ qcomgpio_x1e_translate(ACPI_INTEGER val) } static struct qcomgpio_config qcomgpio_x1e_config = { - .num_pins = 239, + .num_pins = X1E_NUM_PINS, .translate = qcomgpio_x1e_translate, }; @@ -186,12 +193,35 @@ qcomgpio_attach(device_t parent, device_ sc->sc_pins = kmem_zalloc(sizeof(*sc->sc_pins) * sc->sc_config->num_pins, KM_SLEEP); for (pin = 0; pin < sc->sc_config->num_pins; pin++) { +#if notyet + uint32_t ctl, func; + + aprint_debuf_dev(self, "pin %u: ", pin); + ctl = RD4(sc, TLMM_GPIO_CTL(pin)); + func = __SHIFTOUT(ctl, TLMM_GPIO_CTL_MUX); + + sc->sc_pins[pin].pin_caps = 0; + if (func == TLMM_GPIO_CTL_MUX_GPIO) { + if ((ctl & TLMM_GPIO_CTL_OE) != 0) { + sc->sc_pins[pin].pin_caps |= GPIO_PIN_OUTPUT; + aprint_debug("gpio output\n"); + } else { + sc->sc_pins[pin].pin_caps |= GPIO_PIN_INPUT; + aprint_debug("gpio input\n"); + } + } else { + aprint_debug("func %#x\n", func); + } +#else + sc->sc_pins[pin].pin_caps = + GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; +#endif sc->sc_pins[pin].pin_num = pin; - sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; sc->sc_pins[pin].pin_intrcaps = GPIO_INTR_POS_EDGE | GPIO_INTR_NEG_EDGE | GPIO_INTR_DOUBLE_EDGE | GPIO_INTR_HIGH_LEVEL | GPIO_INTR_LOW_LEVEL | GPIO_INTR_MPSAFE; + /* It's not safe to read all pins, so leave pin state unknown */ sc->sc_pins[pin].pin_state = 0; } @@ -238,12 +268,13 @@ done: } static int -qcomgpio_acpi_translate(void *priv, ACPI_INTEGER pin, void **gpiop) +qcomgpio_acpi_translate(void *priv, ACPI_RESOURCE_GPIO *gpio, void **gpiop) { struct qcomgpio_softc * const sc = priv; + const ACPI_INTEGER pin = gpio->PinTable[0]; int xpin; - xpin = sc->sc_config->translate(pin); + xpin = sc->sc_config->translate(gpio); aprint_debug_dev(sc->sc_dev, "translate %#lx -> %u\n", pin, xpin); @@ -278,7 +309,7 @@ qcomgpio_register_event(void *priv, stru int irqmode; void *ih; - const int pin = qcomgpio_acpi_translate(sc, gpio->PinTable[0], NULL); + const int pin = qcomgpio_acpi_translate(sc, gpio, NULL); if (pin < 0) { aprint_error_dev(sc->sc_dev, @@ -308,6 +339,10 @@ qcomgpio_register_event(void *priv, stru aprint_error_dev(sc->sc_dev, "couldn't register event for pin %#x\n", gpio->PinTable[0]); + return; + } + if (gpio->Triggering == ACPI_LEVEL_SENSITIVE) { + acpi_event_set_intrcookie(ev, ih); } } @@ -320,6 +355,9 @@ qcomgpio_pin_read(void *priv, int pin) if (pin < 0 || pin >= sc->sc_config->num_pins) { return 0; } + if ((sc->sc_pins[pin].pin_caps & GPIO_PIN_INPUT) == 0) { + return 0; + } val = RD4(sc, TLMM_GPIO_IN_OUT(pin)); return (val & TLMM_GPIO_IN_OUT_GPIO_IN) != 0; @@ -334,6 +372,9 @@ qcomgpio_pin_write(void *priv, int pin, if (pin < 0 || pin >= sc->sc_config->num_pins) { return; } + if ((sc->sc_pins[pin].pin_caps & GPIO_PIN_OUTPUT) == 0) { + return; + } val = RD4(sc, TLMM_GPIO_IN_OUT(pin)); if (pinval) { @@ -372,6 +413,8 @@ qcomgpio_intr_establish(void *priv, int qih->ih_func = func; qih->ih_arg = arg; qih->ih_pin = pin; + qih->ih_type = (irqmode & GPIO_INTR_LEVEL_MASK) != 0 ? + IST_LEVEL : IST_EDGE; mutex_enter(&sc->sc_lock); @@ -462,6 +505,9 @@ qcomgpio_intr_mask(void *priv, void *ih) uint32_t val; val = RD4(sc, TLMM_GPIO_INTR_CFG(qih->ih_pin)); + if (qih->ih_type == IST_LEVEL) { + val &= ~TLMM_GPIO_INTR_CFG_INTR_RAW_STATUS_EN; + } val &= ~TLMM_GPIO_INTR_CFG_INTR_ENABLE; WR4(sc, TLMM_GPIO_INTR_CFG(qih->ih_pin), val); } @@ -474,6 +520,9 @@ qcomgpio_intr_unmask(void *priv, void *i uint32_t val; val = RD4(sc, TLMM_GPIO_INTR_CFG(qih->ih_pin)); + if (qih->ih_type == IST_LEVEL) { + val |= TLMM_GPIO_INTR_CFG_INTR_RAW_STATUS_EN; + } val |= TLMM_GPIO_INTR_CFG_INTR_ENABLE; WR4(sc, TLMM_GPIO_INTR_CFG(qih->ih_pin), val); } Index: src/sys/dev/acpi/qcomgpioreg.h diff -u src/sys/dev/acpi/qcomgpioreg.h:1.1 src/sys/dev/acpi/qcomgpioreg.h:1.2 --- src/sys/dev/acpi/qcomgpioreg.h:1.1 Sun Dec 8 20:49:14 2024 +++ src/sys/dev/acpi/qcomgpioreg.h Mon Dec 9 22:10:25 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: qcomgpioreg.h,v 1.1 2024/12/08 20:49:14 jmcneill Exp $ */ +/* $NetBSD: qcomgpioreg.h,v 1.2 2024/12/09 22:10:25 jmcneill Exp $ */ /* * Copyright (c) 2022 Mark Kettenis <kette...@openbsd.org> * @@ -20,6 +20,11 @@ #define _TLMM_GPIO_PIN_OFFSET(pin, reg) ((pin) * 0x1000 + (reg)) +#define TLMM_GPIO_CTL(pin) _TLMM_GPIO_PIN_OFFSET(pin, 0x0) +#define TLMM_GPIO_CTL_OE __BIT(9) +#define TLMM_GPIO_CTL_MUX __BITS(5,2) +#define TLMM_GPIO_CTL_MUX_GPIO 0 + #define TLMM_GPIO_IN_OUT(pin) _TLMM_GPIO_PIN_OFFSET(pin, 0x4) #define TLMM_GPIO_IN_OUT_GPIO_IN __BIT(0) #define TLMM_GPIO_IN_OUT_GPIO_OUT __BIT(1) Index: src/sys/dev/acpi/acpivar.h diff -u src/sys/dev/acpi/acpivar.h:1.91 src/sys/dev/acpi/acpivar.h:1.92 --- src/sys/dev/acpi/acpivar.h:1.91 Sun Dec 8 20:49:14 2024 +++ src/sys/dev/acpi/acpivar.h Mon Dec 9 22:10:25 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: acpivar.h,v 1.91 2024/12/08 20:49:14 jmcneill Exp $ */ +/* $NetBSD: acpivar.h,v 1.92 2024/12/09 22:10:25 jmcneill Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -136,7 +136,7 @@ struct acpi_devnode { bus_dma_tag_t ad_dmat64; /* Bus DMA tag for device (64-bit) */ device_t ad_gpiodev; /* GPIO controller device */ - int (*ad_gpio_translate)(void *, ACPI_INTEGER, void **); + int (*ad_gpio_translate)(void *, ACPI_RESOURCE_GPIO *, void **); void *ad_gpio_priv; /* private data for translate */ SIMPLEQ_ENTRY(acpi_devnode) ad_list;