use machdep.lidsuspend=2 for hibernate

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

use machdep.lidsuspend=2 for hibernate

Martin Natano
This diff has been sitting in my patches folder for weeks now - posting
it now for discussion. What it does is to extend the machdep.lidsuspend
sysctl to also cover hibernate. I think it might be interesting for
users of a laptop/netbook where suspend tends to drain the battery, like
my MSI Wind U100 does. Unfortunately The U100 doesn't even report lid
status, but that's another story...

The machdep.lidsuspend sysctl is currently used like this: The value
zero does nothing and every other value causes the system to suspend
when the lid is being closed. I propose slightly different semantics:
The value zero does nothing (as before), the value one causes the
system to suspend (as before) and the value two initiates hibernation.
All other values do not cause any effect.

cheers,
natano


(tested on my Thinkpad T520 / amd64)

Index: etc/etc.amd64/sysctl.conf
===================================================================
RCS file: /cvs/src/etc/etc.amd64/sysctl.conf,v
retrieving revision 1.6
diff -u -p -u -r1.6 sysctl.conf
--- etc/etc.amd64/sysctl.conf 16 Jun 2015 20:30:24 -0000 1.6
+++ etc/etc.amd64/sysctl.conf 12 Oct 2015 20:44:39 -0000
@@ -1,3 +1,4 @@
 #machdep.allowaperture=2 # See xf86(4)
 #machdep.kbdreset=1 # permit console CTRL-ALT-DEL to do a nice halt
 #machdep.lidsuspend=0 # do not suspend laptop upon lid closing
+#machdep.lidsuspend=2 # put system into hibernation upon lid closing
Index: etc/etc.i386/sysctl.conf
===================================================================
RCS file: /cvs/src/etc/etc.i386/sysctl.conf,v
retrieving revision 1.18
diff -u -p -u -r1.18 sysctl.conf
--- etc/etc.i386/sysctl.conf 16 Jun 2015 20:30:24 -0000 1.18
+++ etc/etc.i386/sysctl.conf 12 Oct 2015 20:44:39 -0000
@@ -2,6 +2,7 @@
 #machdep.apmhalt=1 # 1=powerdown hack, try if halt -p doesn't work
 #machdep.kbdreset=1 # permit console CTRL-ALT-DEL to do a nice halt
 #machdep.lidsuspend=0 # do not suspend laptop upon lid closing
+#machdep.lidsuspend=2 # put system into hibernation upon lid closing
 #machdep.userldt=1 # allow userland programs to play with ldt,
  # required by some ports
 #kern.emul.linux=1 # enable running Linux binaries
Index: sys/dev/acpi/acpibtn.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpibtn.c,v
retrieving revision 1.41
diff -u -p -u -r1.41 acpibtn.c
--- sys/dev/acpi/acpibtn.c 27 Jan 2015 19:40:14 -0000 1.41
+++ sys/dev/acpi/acpibtn.c 12 Oct 2015 20:44:49 -0000
@@ -16,11 +16,16 @@
  */
 
 #include <sys/param.h>
+#include <sys/conf.h>
 #include <sys/signalvar.h>
 #include <sys/systm.h>
 #include <sys/device.h>
 #include <sys/malloc.h>
 
+#ifdef HIBERNATE
+#include <sys/hibernate.h>
+#endif
+
 #include <machine/bus.h>
 #include <machine/apmvar.h>
 
@@ -225,10 +230,28 @@ acpibtn_notify(struct aml_node *node, in
     "_LID", 0, NULL, &lid))
  return (0);
  sc->sc_sens.value = lid;
- if (lid_suspend == 0)
+
+ if (lid != 0)
  break;
- if (lid == 0)
+
+ switch (lid_suspend) {
+ case 1:
  goto sleep;
+#ifdef HIBERNATE
+ case 2:
+ if (get_hibernate_io_function(swdevt[0].sw_dev) == NULL)
+ return (EOPNOTSUPP);
+
+ /* Request to go to hibernation */
+ if (acpi_record_event(sc->sc_acpi, APM_USER_HIBERNATE_REQ))
+ acpi_addtask(sc->sc_acpi, acpi_sleep_task,
+    sc->sc_acpi, ACPI_STATE_S4);
+ break;
+#endif /* HIBERNATE */
+ case 0:
+ default:
+ break;
+ }
 #endif /* SMALL_KERNEL */
  break;
  case ACPIBTN_SLEEP: