summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2010-05-22 07:35:17 +0000
committerjkim <jkim@FreeBSD.org>2010-05-22 07:35:17 +0000
commit64e597f0789096550e2a46dcc41cb59d447a9fc3 (patch)
tree321148f56fd04d09715225b8a1c8f81799568e13
parent810a32455d43efc2de222a2109f0691456aa7645 (diff)
downloadFreeBSD-src-64e597f0789096550e2a46dcc41cb59d447a9fc3.zip
FreeBSD-src-64e597f0789096550e2a46dcc41cb59d447a9fc3.tar.gz
Suspend screen updates when the video controller is powered down.
-rw-r--r--sys/dev/syscons/syscons.c4
-rw-r--r--sys/dev/syscons/syscons.h1
-rw-r--r--sys/isa/syscons_isa.c101
3 files changed, 89 insertions, 17 deletions
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 9128393..4bf5e15 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -1692,7 +1692,7 @@ sccnupdate(scr_stat *scp)
{
/* this is a cut-down version of scrn_timer()... */
- if (scp->sc->font_loading_in_progress)
+ if (scp->sc->suspend_in_progress || scp->sc->font_loading_in_progress)
return;
if (debugger > 0 || panicstr || shutdown_in_progress) {
@@ -1742,7 +1742,7 @@ scrn_timer(void *arg)
return;
/* don't do anything when we are performing some I/O operations */
- if (sc->font_loading_in_progress) {
+ if (sc->suspend_in_progress || sc->font_loading_in_progress) {
if (again)
timeout(scrn_timer, sc, hz / 10);
return;
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index a23f884..5efdb98 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -230,6 +230,7 @@ typedef struct sc_softc {
char switch_in_progress;
char write_in_progress;
char blink_in_progress;
+ char suspend_in_progress;
struct mtx video_mtx;
long scrn_time_stamp;
diff --git a/sys/isa/syscons_isa.c b/sys/isa/syscons_isa.c
index 237e188..986789e 100644
--- a/sys/isa/syscons_isa.c
+++ b/sys/isa/syscons_isa.c
@@ -114,21 +114,21 @@ scsuspend(device_t dev)
sc = &main_softc;
- if (sc->cur_scp == NULL)
+ if (sc->cur_scp == NULL || sc->suspend_in_progress)
return (0);
- sc_cur_scr = sc->cur_scp->index;
-
- if (sc_no_suspend_vtswitch)
- return (0);
+ if (!sc_no_suspend_vtswitch) {
+ sc_cur_scr = sc->cur_scp->index;
+ do {
+ sc_switch_scr(sc, 0);
+ if (!sc->switch_in_progress) {
+ break;
+ }
+ pause("scsuspend", hz);
+ } while (retry--);
+ }
- do {
- sc_switch_scr(sc, 0);
- if (!sc->switch_in_progress) {
- break;
- }
- pause("scsuspend", hz);
- } while (retry--);
+ sc->suspend_in_progress = TRUE;
return (0);
}
@@ -138,11 +138,15 @@ scresume(device_t dev)
{
sc_softc_t *sc;
- if (sc_no_suspend_vtswitch)
+ sc = &main_softc;
+
+ if (!sc->suspend_in_progress)
return (0);
- sc = &main_softc;
- sc_switch_scr(sc, sc_cur_scr);
+ sc->suspend_in_progress = FALSE;
+
+ if (!sc_no_suspend_vtswitch)
+ sc_switch_scr(sc, sc_cur_scr);
return (0);
}
@@ -303,3 +307,70 @@ static driver_t sc_driver = {
};
DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0);
+
+static devclass_t scpm_devclass;
+
+static void
+scpm_identify(driver_t *driver, device_t parent)
+{
+
+ device_add_child(parent, "scpm", 0);
+}
+
+static int
+scpm_probe(device_t dev)
+{
+
+ device_set_desc(dev, SC_DRIVER_NAME " suspend/resume");
+ device_quiet(dev);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+scpm_attach(device_t dev)
+{
+
+ bus_generic_probe(dev);
+ bus_generic_attach(dev);
+
+ return (0);
+}
+
+static int
+scpm_suspend(device_t dev)
+{
+ int error;
+
+ error = bus_generic_suspend(dev);
+ if (error != 0)
+ return (error);
+
+ return (scsuspend(dev));
+}
+
+static int
+scpm_resume(device_t dev)
+{
+
+ scresume(dev);
+
+ return (bus_generic_resume(dev));
+}
+
+static device_method_t scpm_methods[] = {
+ DEVMETHOD(device_identify, scpm_identify),
+ DEVMETHOD(device_probe, scpm_probe),
+ DEVMETHOD(device_attach, scpm_attach),
+ DEVMETHOD(device_suspend, scpm_suspend),
+ DEVMETHOD(device_resume, scpm_resume),
+ { 0, 0 }
+};
+
+static driver_t scpm_driver = {
+ "scpm",
+ scpm_methods,
+ 0
+};
+
+DRIVER_MODULE(scpm, vgapm, scpm_driver, scpm_devclass, 0, 0);
OpenPOWER on IntegriCloud