Index | Thread | Search

From:
Mark Kettenis <mark.kettenis@xs4all.nl>
Subject:
Re: amdgpio(4): add wakeup support
To:
James Hastings <moosetek4@gmail.com>
Cc:
tech@openbsd.org,moosetek4@gmail.com
Date:
Tue, 03 Jun 2025 21:40:59 +0200

Download raw body.

Thread
> From: James Hastings <moosetek4@gmail.com>
> Date: Mon, 2 Jun 2025 18:37:39 -0400 (EDT)

Hi James,

> Diff below does two things:
> 
> (1) Teach acpi(4) about gpio wakeup resources.
> 
> (2) Add gpio wakeup support to amdgpio(4).
> 
> At suspend time the driver saves the pin configuration as before but now
> disables all non-wakeup interrupts.
> 
> ok?

I don't think this is enough to actually wake the machine up as the
acpi code will send the machine straight back to sleep as you don't
set sc_wakeup in the acpi(4) softc.

Also, my understanding is that the LR_GPIO_WAKE flag marks a GPIO as
wakeup *capable*.  But we don't necessarily want to configure all
wakeup capable GPIOs to actually wake up the system.  That will just
result in spurious wakeups.

I sent out the diff below that handles the upper layers and passes
down IPL_WAKEUP to the GPIO drivers.  But some of your bits make me
suspect that I'm missing some stuff in my code.

I haven't had any test reports for my diff yet, but I'd like to find
if it works or not.  And if it doesn't I'd like to roll in some of the
bits from your diff to see if they help.  Is that ok with you?


> Index: dev/acpi/dsdt.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/dsdt.h,v
> retrieving revision 1.82
> diff -u -p -r1.82 dsdt.h
> --- dev/acpi/dsdt.h	13 May 2024 01:15:50 -0000	1.82
> +++ dev/acpi/dsdt.h	2 Jun 2025 22:04:02 -0000
> @@ -243,6 +243,9 @@ union acpi_resource {
>  		uint16_t	flags;
>  		uint16_t	tflags;
>  #define LR_GPIO_SHR		(3L << 3)
> +#define  LR_GPIO_EXCLUSIVE	(0L << 3)
> +#define  LR_GPIO_SHARED		(1L << 3)
> +#define  LR_GPIO_WAKE		(2L << 3)
>  #define LR_GPIO_POLARITY	(3L << 1)
>  #define  LR_GPIO_ACTHI		(0L << 1)
>  #define  LR_GPIO_ACTLO		(1L << 1)
> Index: dev/acpi/amdgpio.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/amdgpio.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 amdgpio.c
> --- dev/acpi/amdgpio.c	20 Oct 2022 20:40:57 -0000	1.10
> +++ dev/acpi/amdgpio.c	2 Jun 2025 22:04:02 -0000
> @@ -32,10 +32,15 @@
>  #define AMDGPIO_CONF_MASK		0x00000600
>  #define AMDGPIO_CONF_INT_EN		0x00000800
>  #define AMDGPIO_CONF_INT_MASK		0x00001000
> +#define AMDGPIO_CONF_WAKE_S0		0x00002000
> +#define AMDGPIO_CONF_WAKE_S3		0x00004000
> +#define AMDGPIO_CONF_WAKE_S4		0x00008000
> +#define AMDGPIO_CONF_WAKE_MASK		0x0000e000
>  #define AMDGPIO_CONF_RXSTATE		0x00010000
>  #define AMDGPIO_CONF_TXSTATE		0x00400000
>  #define AMDGPIO_CONF_TXSTATE_EN		0x00800000
>  #define AMDGPIO_CONF_INT_STS		0x10000000
> +#define AMDGPIO_CONF_WAKE_STS		0x20000000
>  #define AMDGPIO_IRQ_MASTER_EOI		0x20000000
>  #define AMDGPIO_IRQ_BITS		46
>  #define AMDGPIO_IRQ_PINS		4
> @@ -155,7 +160,7 @@ amdgpio_attach(struct device *parent, st
>  	    M_DEVBUF, M_WAITOK | M_ZERO);
>  
>  	sc->sc_ih = acpi_intr_establish(aaa->aaa_irq[0], aaa->aaa_irq_flags[0],
> -	    IPL_BIO, amdgpio_intr, sc, sc->sc_dev.dv_xname);
> +	    IPL_BIO | IPL_WAKEUP, amdgpio_intr, sc, sc->sc_dev.dv_xname);
>  	if (sc->sc_ih == NULL) {
>  		printf(": can't establish interrupt\n");
>  		goto unmap;
> @@ -201,6 +206,10 @@ amdgpio_save_pin(struct amdgpio_softc *s
>  {
>  	sc->sc_pin_cfg[pin].pin_cfg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
>  	    pin * 4);
> +
> +	if (sc->sc_pin_ih[pin].ih_func &&
> +	    (sc->sc_pin_cfg[pin].pin_cfg & AMDGPIO_CONF_WAKE_MASK) == 0)
> +		amdgpio_intr_disable(sc, pin);
>  }
>  
>  void
> @@ -271,13 +280,15 @@ amdgpio_intr_establish(void *cookie, int
>  
>  	reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4);
>  	reg &= ~(AMDGPIO_CONF_MASK | AMDGPIO_CONF_LEVEL |
> -	    AMDGPIO_CONF_TXSTATE_EN);
> +	    AMDGPIO_CONF_TXSTATE_EN | AMDGPIO_CONF_WAKE_MASK);
>  	if ((flags & LR_GPIO_MODE) == 0)
>  		reg |= AMDGPIO_CONF_LEVEL;
>  	if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTLO)
>  		reg |= AMDGPIO_CONF_ACTLO;
>  	if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTBOTH)
>  		reg |= AMDGPIO_CONF_ACTBOTH;
> +	if ((flags & LR_GPIO_WAKE) == LR_GPIO_WAKE)
> +		reg |= AMDGPIO_CONF_WAKE_S0;
>  	reg |= (AMDGPIO_CONF_INT_MASK | AMDGPIO_CONF_INT_EN);
>  	bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4, reg);
>  }
> 
> 

Index: arch/amd64/amd64/intr.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/intr.c,v
diff -u -p -r1.62 intr.c
--- arch/amd64/amd64/intr.c	23 Apr 2025 15:08:05 -0000	1.62
+++ arch/amd64/amd64/intr.c	31 May 2025 20:15:47 -0000
@@ -712,6 +712,13 @@ intr_barrier(void *cookie)
 	sched_barrier(ih->ih_cpu);
 }
 
+void
+intr_set_wakeup(void *cookie)
+{
+	struct intrhand *ih = cookie;
+	ih->ih_flags |= IPL_WAKEUP;
+}
+
 #ifdef SUSPEND
 
 void
Index: arch/amd64/include/intr.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/intr.h,v
diff -u -p -r1.35 intr.h
--- arch/amd64/include/intr.h	23 Apr 2025 15:08:05 -0000	1.35
+++ arch/amd64/include/intr.h	31 May 2025 20:15:47 -0000
@@ -210,6 +210,7 @@ int intr_handler(struct intrframe *, str
 void cpu_intr_init(struct cpu_info *);
 void intr_printconfig(void);
 void intr_barrier(void *);
+void intr_set_wakeup(void *);
 void intr_enable_wakeup(void);
 void intr_disable_wakeup(void);
 
Index: dev/acpi/acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
diff -u -p -r1.447 acpi.c
--- dev/acpi/acpi.c	28 May 2025 09:53:53 -0000	1.447
+++ dev/acpi/acpi.c	31 May 2025 20:15:47 -0000
@@ -945,7 +945,8 @@ acpi_gpio_parse_events(int crsidx, union
 			ev->tflags = crs->lr_gpio.tflags;
 			ev->pin = pin;
 			gpio->intr_establish(gpio->cookie, pin,
-			    crs->lr_gpio.tflags, acpi_gpio_event, ev);
+			    crs->lr_gpio.tflags, IPL_BIO | IPL_WAKEUP,
+			    acpi_gpio_event, ev);
 		}
 		break;
 	default:
Index: dev/acpi/amdgpio.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/amdgpio.c,v
diff -u -p -r1.10 amdgpio.c
--- dev/acpi/amdgpio.c	20 Oct 2022 20:40:57 -0000	1.10
+++ dev/acpi/amdgpio.c	31 May 2025 20:15:47 -0000
@@ -46,6 +46,7 @@
 struct amdgpio_intrhand {
 	int (*ih_func)(void *);
 	void *ih_arg;
+	int ih_wakeup;
 };
 
 struct amdgpio_pincfg {
@@ -91,7 +92,7 @@ const char *amdgpio_hids[] = {
 
 int	amdgpio_read_pin(void *, int);
 void	amdgpio_write_pin(void *, int, int);
-void	amdgpio_intr_establish(void *, int, int, int (*)(void *), void *);
+void	amdgpio_intr_establish(void *, int, int, int, int (*)(void *), void *);
 void	amdgpio_intr_enable(void *, int);
 void	amdgpio_intr_disable(void *, int);
 int	amdgpio_pin_intr(struct amdgpio_softc *, int);
@@ -258,7 +259,7 @@ amdgpio_write_pin(void *cookie, int pin,
 }
 
 void
-amdgpio_intr_establish(void *cookie, int pin, int flags,
+amdgpio_intr_establish(void *cookie, int pin, int flags, int level,
     int (*func)(void *), void *arg)
 {
 	struct amdgpio_softc *sc = cookie;
@@ -268,6 +269,7 @@ amdgpio_intr_establish(void *cookie, int
 
 	sc->sc_pin_ih[pin].ih_func = func;
 	sc->sc_pin_ih[pin].ih_arg = arg;
+	sc->sc_pin_ih[pin].ih_wakeup = level & IPL_WAKEUP;
 
 	reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4);
 	reg &= ~(AMDGPIO_CONF_MASK | AMDGPIO_CONF_LEVEL |
@@ -280,6 +282,9 @@ amdgpio_intr_establish(void *cookie, int
 		reg |= AMDGPIO_CONF_ACTBOTH;
 	reg |= (AMDGPIO_CONF_INT_MASK | AMDGPIO_CONF_INT_EN);
 	bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4, reg);
+
+	if (sc->sc_pin_ih[pin].ih_wakeup)
+		intr_set_wakeup(sc->sc_ih);
 }
 
 void
Index: dev/acpi/amltypes.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/amltypes.h,v
diff -u -p -r1.50 amltypes.h
--- dev/acpi/amltypes.h	2 Jun 2024 11:08:41 -0000	1.50
+++ dev/acpi/amltypes.h	31 May 2025 20:15:47 -0000
@@ -369,7 +369,8 @@ struct acpi_gpio {
 	void	*cookie;
 	int	(*read_pin)(void *, int);
 	void	(*write_pin)(void *, int, int);
-	void	(*intr_establish)(void *, int, int, int (*)(void *), void *);
+	void	(*intr_establish)(void *, int, int, int,
+		    int (*)(void *), void *);
 	void	(*intr_enable)(void *, int);
 	void	(*intr_disable)(void *, int);
 };
Index: dev/acpi/aplgpio.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/aplgpio.c,v
diff -u -p -r1.6 aplgpio.c
--- dev/acpi/aplgpio.c	20 Oct 2022 20:40:57 -0000	1.6
+++ dev/acpi/aplgpio.c	31 May 2025 20:15:47 -0000
@@ -75,7 +75,7 @@ const char *aplgpio_hids[] = {
 
 int	aplgpio_read_pin(void *, int);
 void	aplgpio_write_pin(void *, int, int);
-void	aplgpio_intr_establish(void *, int, int, int (*)(void *), void *);
+void	aplgpio_intr_establish(void *, int, int, int, int (*)(void *), void *);
 void	aplgpio_intr_enable(void *, int);
 void	aplgpio_intr_disable(void *, int);
 int	aplgpio_intr(void *);
@@ -205,7 +205,7 @@ aplgpio_write_pin(void *cookie, int pin,
 }
 
 void
-aplgpio_intr_establish(void *cookie, int pin, int flags,
+aplgpio_intr_establish(void *cookie, int pin, int flags, int level,
     int (*func)(void *), void *arg)
 {
 	struct aplgpio_softc *sc = cookie;
Index: dev/acpi/bytgpio.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/bytgpio.c,v
diff -u -p -r1.18 bytgpio.c
--- dev/acpi/bytgpio.c	20 Oct 2022 20:40:57 -0000	1.18
+++ dev/acpi/bytgpio.c	31 May 2025 20:15:47 -0000
@@ -102,7 +102,7 @@ const int byt_sus_pins[] = {
 
 int	bytgpio_read_pin(void *, int);
 void	bytgpio_write_pin(void *, int, int);
-void	bytgpio_intr_establish(void *, int, int, int (*)(void *), void *);
+void	bytgpio_intr_establish(void *, int, int, int, int (*)(void *), void *);
 void	bytgpio_intr_enable(void *, int);
 void	bytgpio_intr_disable(void *, int);
 int	bytgpio_intr(void *);
@@ -234,7 +234,7 @@ bytgpio_write_pin(void *cookie, int pin,
 }
 
 void
-bytgpio_intr_establish(void *cookie, int pin, int flags,
+bytgpio_intr_establish(void *cookie, int pin, int flags, int level,
     int (*func)(void *), void *arg)
 {
 	struct bytgpio_softc *sc = cookie;
Index: dev/acpi/chvgpio.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/chvgpio.c,v
diff -u -p -r1.13 chvgpio.c
--- dev/acpi/chvgpio.c	20 Oct 2022 20:40:57 -0000	1.13
+++ dev/acpi/chvgpio.c	31 May 2025 20:15:47 -0000
@@ -145,7 +145,7 @@ const int chv_southeast_pins[] = {
 int	chvgpio_check_pin(struct chvgpio_softc *, int);
 int	chvgpio_read_pin(void *, int);
 void	chvgpio_write_pin(void *, int, int);
-void	chvgpio_intr_establish(void *, int, int, int (*)(void *), void *);
+void	chvgpio_intr_establish(void *, int, int, int, int (*)(void *), void *);
 void	chvgpio_intr_enable(void *, int);
 void	chvgpio_intr_disable(void *, int);
 int	chvgpio_intr(void *);
@@ -291,7 +291,7 @@ chvgpio_write_pin(void *cookie, int pin,
 }
 
 void
-chvgpio_intr_establish(void *cookie, int pin, int flags,
+chvgpio_intr_establish(void *cookie, int pin, int flags, int level,
     int (*func)(void *), void *arg)
 {
 	struct chvgpio_softc *sc = cookie;
Index: dev/acpi/dwgpio.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dwgpio.c,v
diff -u -p -r1.8 dwgpio.c
--- dev/acpi/dwgpio.c	13 May 2024 01:15:50 -0000	1.8
+++ dev/acpi/dwgpio.c	31 May 2025 20:15:47 -0000
@@ -90,7 +90,7 @@ const char *dwgpio_hids[] = {
 int	dwgpio_found_hid(struct aml_node *, void *);
 int	dwgpio_read_pin(void *, int);
 void	dwgpio_write_pin(void *, int, int);
-void	dwgpio_intr_establish(void *, int, int, int (*)(void *), void *);
+void	dwgpio_intr_establish(void *, int, int, int, int (*)(void *), void *);
 int	dwgpio_intr(void *);
 
 int
@@ -228,7 +228,7 @@ dwgpio_write_pin(void *cookie, int pin, 
 }
 
 void
-dwgpio_intr_establish(void *cookie, int pin, int flags,
+dwgpio_intr_establish(void *cookie, int pin, int flags, int level,
     int (*func)(void *), void *arg)
 {
 	struct dwgpio_softc *sc = cookie;
Index: dev/acpi/dwiic_acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dwiic_acpi.c,v
diff -u -p -r1.22 dwiic_acpi.c
--- dev/acpi/dwiic_acpi.c	8 Jul 2023 02:43:02 -0000	1.22
+++ dev/acpi/dwiic_acpi.c	31 May 2025 20:15:47 -0000
@@ -387,7 +387,7 @@ dwiic_i2c_intr_establish(void *cookie, v
 
 		struct acpi_gpio *gpio = crs->gpio_int_node->gpio;
 		gpio->intr_establish(gpio->cookie, crs->gpio_int_pin,
-				     crs->gpio_int_flags, func, arg);
+		    crs->gpio_int_flags, level, func, arg);
 		return ih;
 	}
 
Index: dev/acpi/glkgpio.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/glkgpio.c,v
diff -u -p -r1.7 glkgpio.c
--- dev/acpi/glkgpio.c	13 May 2024 01:15:50 -0000	1.7
+++ dev/acpi/glkgpio.c	31 May 2025 20:15:47 -0000
@@ -75,7 +75,7 @@ const char *glkgpio_hids[] = {
 
 int	glkgpio_read_pin(void *, int);
 void	glkgpio_write_pin(void *, int, int);
-void	glkgpio_intr_establish(void *, int, int, int (*)(void *), void *);
+void	glkgpio_intr_establish(void *, int, int, int, int (*)(void *), void *);
 void	glkgpio_intr_enable(void *, int);
 void	glkgpio_intr_disable(void *, int);
 int	glkgpio_intr(void *);
@@ -205,7 +205,7 @@ glkgpio_write_pin(void *cookie, int pin,
 }
 
 void
-glkgpio_intr_establish(void *cookie, int pin, int flags,
+glkgpio_intr_establish(void *cookie, int pin, int flags, int level,
     int (*func)(void *), void *arg)
 {
 	struct glkgpio_softc *sc = cookie;
Index: dev/acpi/pchgpio.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/pchgpio.c,v
diff -u -p -r1.16 pchgpio.c
--- dev/acpi/pchgpio.c	18 Aug 2024 11:10:10 -0000	1.16
+++ dev/acpi/pchgpio.c	31 May 2025 20:15:47 -0000
@@ -463,7 +463,7 @@ struct pchgpio_match pchgpio_devices[] =
 
 int	pchgpio_read_pin(void *, int);
 void	pchgpio_write_pin(void *, int, int);
-void	pchgpio_intr_establish(void *, int, int, int (*)(void *), void *);
+void	pchgpio_intr_establish(void *, int, int, int, int (*)(void *), void *);
 void	pchgpio_intr_enable(void *, int);
 void	pchgpio_intr_disable(void *, int);
 int	pchgpio_intr(void *);
@@ -640,7 +640,7 @@ pchgpio_write_pin(void *cookie, int pin,
 }
 
 void
-pchgpio_intr_establish(void *cookie, int pin, int flags,
+pchgpio_intr_establish(void *cookie, int pin, int flags, int level,
     int (*func)(void *), void *arg)
 {
 	struct pchgpio_softc *sc = cookie;
Index: dev/acpi/pckbc_acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/pckbc_acpi.c,v
diff -u -p -r1.4 pckbc_acpi.c
--- dev/acpi/pckbc_acpi.c	28 May 2025 07:04:27 -0000	1.4
+++ dev/acpi/pckbc_acpi.c	31 May 2025 20:15:47 -0000
@@ -290,8 +290,8 @@ pckbc_acpi_attach_kbd(struct device *par
 			if (pasc->sc_nints == nitems(pasc->sc_ih))
 				break;
 			pasc->sc_ih[pasc->sc_nints] = acpi_intr_establish(
-			    aaa->aaa_irq[irq], aaa->aaa_irq_flags[irq], IPL_TTY,
-			    pckbcintr, pasc, self->dv_xname);
+			    aaa->aaa_irq[irq], aaa->aaa_irq_flags[irq],
+			    IPL_TTY, pckbcintr, pasc, self->dv_xname);
 			if (pasc->sc_ih[pasc->sc_nints] == NULL) {
 				printf("%s: can't establish interrupt %d\n",
 				    self->dv_xname, aaa->aaa_irq[irq]);
@@ -392,8 +392,8 @@ pckbc_acpi_attach_mouse(struct device *p
 			if (pasc->sc_nints == nitems(pasc->sc_ih))
 				break;
 			pasc->sc_ih[pasc->sc_nints] = acpi_intr_establish(
-			    aaa->aaa_irq[irq], aaa->aaa_irq_flags[irq], IPL_TTY,
-			    pckbcintr, pasc, self->dv_xname);
+			    aaa->aaa_irq[irq], aaa->aaa_irq_flags[irq],
+			    IPL_TTY, pckbcintr, pasc, self->dv_xname);
 			if (pasc->sc_ih[pasc->sc_nints] == NULL) {
 				printf("%s: can't establish interrupt %d\n",
 				    self->dv_xname, aaa->aaa_irq[irq]);
@@ -433,7 +433,7 @@ pckbc_acpi_register_gpio_intrs(struct de
 		}
 		gpio->intr_establish(gpio->cookie,
 		    sc->sc_gpioint[irq].pin, sc->sc_gpioint[irq].flags,
-		    pckbc_acpi_gpio_intr_wrapper, sc);
+		    IPL_TTY, pckbc_acpi_gpio_intr_wrapper, sc);
 	}
 }
 
Index: dev/acpi/sdhc_acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/sdhc_acpi.c,v
diff -u -p -r1.23 sdhc_acpi.c
--- dev/acpi/sdhc_acpi.c	9 Oct 2024 00:38:25 -0000	1.23
+++ dev/acpi/sdhc_acpi.c	31 May 2025 20:15:47 -0000
@@ -131,7 +131,8 @@ sdhc_acpi_attach(struct device *parent, 
 		struct acpi_gpio *gpio = sc->sc_gpio_int_node->gpio;
 
 		gpio->intr_establish(gpio->cookie, sc->sc_gpio_int_pin,
-		    sc->sc_gpio_int_flags, sdhc_acpi_card_detect_intr, sc);
+		    sc->sc_gpio_int_flags, IPL_BIO,
+		    sdhc_acpi_card_detect_intr, sc);
 	}
 
 	sdhc_acpi_power_on(sc, sc->sc_node);