Machine don't necessarily come out of suspend with CPUs running at the
speed they suspended with.  So we might end up in the situation where
apmd(8) thinks we're running at maximum speed while the CPU is clocked
down to its lowest speed, and that situation perpetuates because
apmd(9) doesn't adjust hw.setperf.  Easiest way out is to just call
cpu_setperf() is the resume path with the current hw.setperf setting.
The apm(4) resume code already does this.  The diff below makes
acpi(4) do the same thing.

I put the call fairly late into the resume path.  Doing it earlier
(before bufq_restart() like the apm(4) code does) broke resume on my
x220.  Perhaps we should adjust apm(4) to do this call later as well.

ok?


Index: acpi.c
===================================================================
RCS file: /home/cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.248
diff -u -p -r1.248 acpi.c
--- acpi.c      6 Dec 2013 21:03:02 -0000       1.248
+++ acpi.c      13 Dec 2013 23:10:10 -0000
@@ -30,6 +30,7 @@
 #include <sys/workq.h>
 #include <sys/sched.h>
 #include <sys/reboot.h>
+#include <sys/sysctl.h>
 
 #ifdef HIBERNATE
 #include <sys/hibernate.h>
@@ -2084,6 +2085,7 @@ acpi_indicator(struct acpi_softc *sc, in
 int
 acpi_sleep_state(struct acpi_softc *sc, int state)
 {
+       extern int perflevel;
        int error = ENXIO;
        int s;
 
@@ -2183,6 +2185,10 @@ fail_quiesce:
 #if NWSDISPLAY > 0
        wsdisplay_resume();
 #endif /* NWSDISPLAY > 0 */
+
+       /* Restore hw.setperf */
+       if (cpu_setperf != NULL)
+               cpu_setperf(perflevel);
 
        acpi_record_event(sc, APM_NORMAL_RESUME);
        acpi_indicator(sc, ACPI_SST_WORKING);

Reply via email to