Index | Thread | Search

From:
James Cook <falsifian@falsifian.org>
Subject:
[PATCH] Don't shut down after power button wakes
To:
tech@openbsd.org
Cc:
Theo de Raadt <deraadt@openbsd.org>
Date:
Sun, 21 Apr 2024 17:04:21 +0000

Download raw body.

Thread
This patch is adapted from one deraadt sent me in February.

Without this patch, if I wake my laptop by pressing the power button,
the laptop shuts down immediately after waking. The patch seems to
solve the problem.

I spent some time trying to be clever and re-enable the power button
right after resuming was done, without using gettime(), but I don't
understand how ACPI events work and could not push the re-enable-ing
late enough. So I ended up sticking with this approach.

Originally reported at
https://marc.info/?l=openbsd-bugs&m=161038121430416&w=2 , but other
bugs I mentioned on that thread have already disappeared.

-- 
James


diff refs/heads/master 16b4fd4f9a94db0f64c04f33b222b076e5808b3c
commit - b809db8c59b9d17241cabc19d997f1eceddcff41
commit + 16b4fd4f9a94db0f64c04f33b222b076e5808b3c
blob - 70b67bb8fa7fb283c773098abb0d31dc01c323d1
blob + da1703340257c980fe491db6323ef439dca4a9ed
--- sys/dev/acpi/acpi.c
+++ sys/dev/acpi/acpi.c
@@ -2014,6 +2014,17 @@ acpi_gpe_task(void *arg0, int gpe)
 	}
 }
 
+/* Ignore the power button for a short time after a resume */
+int
+acpi_buttonvalid(void)
+{
+	extern time_t waketime;
+
+	if (gettime() < waketime + 10)
+		return 0;
+	return 1;
+}
+
 void
 acpi_pbtn_task(void *arg0, int dummy)
 {
@@ -2035,7 +2046,8 @@ acpi_pbtn_task(void *arg0, int dummy)
 	case 0:
 		break;
 	case 1:
-		acpi_addtask(sc, acpi_powerdown_task, sc, 0);
+		if (acpi_buttonvalid())
+			acpi_addtask(sc, acpi_powerdown_task, sc, 0);
 		break;
 #ifndef SMALL_KERNEL
 	case 2:
blob - 373f05e1377fad67f7435b3ba238fdc6fae4fec4
blob + cbced59a97fbb257f3290e769c1eb8ba837553d8
--- sys/dev/acpi/acpibtn.c
+++ sys/dev/acpi/acpibtn.c
@@ -286,8 +286,9 @@ sleep:
 			case 0:
 				break;
 			case 1:
-				acpi_addtask(sc->sc_acpi, acpi_powerdown_task,
-				    sc->sc_acpi, 0);
+				if (acpi_buttonvalid())
+					acpi_addtask(sc->sc_acpi, acpi_powerdown_task,
+					    sc->sc_acpi, 0);
 				break;
 #ifndef SMALL_KERNEL
 			case 2:
blob - 20521653bc8ff99e82a0f7ccb4e498b6a92bf0c7
blob + 2bddceaa6689a1250b10b256a8c24657cd15d2bb
--- sys/dev/acpi/acpivar.h
+++ sys/dev/acpi/acpivar.h
@@ -371,6 +371,7 @@ void	acpi_write_pmreg(struct acpi_softc *, int, int, i
 
 void	acpi_poll(void *);
 void	acpi_sleep(int, char *);
+int	acpi_buttonvalid(void);
 
 int	acpi_matchcls(struct acpi_attach_args *, int, int, int);
 int	acpi_matchhids(struct acpi_attach_args *, const char *[], const char *);
blob - 1b4f406291812c59af2d4fc8e3910e618c063f40
blob + ab1fffb6099d40fcf2db9c5cb090729c20d40cd5
--- sys/kern/subr_suspend.c
+++ sys/kern/subr_suspend.c
@@ -45,6 +45,8 @@ device_register_wakeup(struct device *dev)
 	wakeup_devices++;
 }
 
+time_t waketime;
+
 int
 sleep_state(void *v, int sleepmode)
 {
@@ -180,6 +182,8 @@ fail_suspend:
 	clockintr_cpu_init(NULL);
 	clockintr_trigger();
 
+	waketime = gettime();
+
 	sleep_resume(v);
 	resume_randomness(rndbuf, rndbuflen);
 #ifdef MULTIPROCESSOR