The following diff is probably too big of the hammer for the problem I'm
trying to solve. Maybe miod can shed more light into it.

The idea is that enabling pci_dopm on my lemote helped save up to 5-6%
more battery when the system is suspended.

Time spent      Remaining battery       Remaining battery       pci_dopm
in suspend      (percentage)            (minutes)
------------------------------------------------------------------------
1h              67                      61/57                   no
1h              73                      72/67                   yes

Remaning minutes change after I hit a few keys or commands (like an ls).
But the percentage stays the same. So that's probably another bug...


The only downside is that the console screen came back screwey[1] on resume,
which is what this diff is fixing.

Tested on lemote from console. Seems to work.
Having a few problems with X unrelated to the diff, so I'd appreciate
some tests from X with pci_dopm enabled.
(You can find the global variable in dev/pci/pci.c. Set it to 1.)

Comments, tests and ways of improving the functionality are welcomed.

[1] -- http://irofti.net/tmp/IMG_0836.JPG

Index: arch/loongson/dev/sisfb.c
===================================================================
RCS file: /cvs/src/sys/arch/loongson/dev/sisfb.c,v
retrieving revision 1.4
diff -u -p -r1.4 sisfb.c
--- arch/loongson/dev/sisfb.c   21 Oct 2013 10:36:14 -0000      1.4
+++ arch/loongson/dev/sisfb.c   29 Jan 2014 13:11:46 -0000
@@ -74,9 +74,11 @@ struct sisfb_softc {
 
 int    sisfb_match(struct device *, void *, void *);
 void   sisfb_attach(struct device *, struct device *, void *);
+int    sisfb_activate(struct device *, int);
 
 const struct cfattach sisfb_ca = {
-       sizeof(struct sisfb_softc), sisfb_match, sisfb_attach
+       sizeof(struct sisfb_softc), sisfb_match, sisfb_attach,
+       NULL, sisfb_activate
 };
 
 struct cfdriver sisfb_cd = {
@@ -656,4 +658,29 @@ sisfb_cnattach(bus_space_tag_t memt, bus
        wsdisplay_cnattach(&sisfbcn.wsd, ri, 0, 0, defattr);
 
        return 0;
+}
+
+int
+sisfb_activate(struct device *self, int act)
+{
+       struct sisfb_softc *sc = (struct sisfb_softc *)self;
+       int console = sisfbcn.ri.ri_hw != NULL;
+       int rc = 0;
+
+       printf("sisfb_activate\n");
+
+       switch (act) {
+       case DVACT_RESUME:
+               if (!console) {
+                       if ((rc = sisfb_setup(&sc->sc_fb_store)) != 0) {
+                               printf(": can't setup frame buffer(%d)\n", rc);
+                               return rc;
+                       }
+               }
+               break;
+       default:
+               break;
+       }
+
+       return rc;
 }

Reply via email to