summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/fb/fbd.c18
-rw-r--r--sys/dev/vt/hw/fb/vt_fb.c10
-rw-r--r--sys/dev/vt/hw/fb/vt_fb.h4
-rw-r--r--sys/dev/vt/vt.h11
-rw-r--r--sys/dev/vt/vt_core.c50
5 files changed, 60 insertions, 33 deletions
diff --git a/sys/dev/fb/fbd.c b/sys/dev/fb/fbd.c
index ff2488d..6bd5766 100644
--- a/sys/dev/fb/fbd.c
+++ b/sys/dev/fb/fbd.c
@@ -332,22 +332,6 @@ fbd_detach(device_t dev)
return (err);
}
-static int
-fbd_suspend(device_t dev)
-{
-
- vt_fb_suspend();
- return (bus_generic_suspend(dev));
-}
-
-static int
-fbd_resume(device_t dev)
-{
-
- vt_fb_resume();
- return (bus_generic_resume(dev));
-}
-
static device_method_t fbd_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, fbd_probe),
@@ -355,8 +339,6 @@ static device_method_t fbd_methods[] = {
DEVMETHOD(device_detach, fbd_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, fbd_suspend),
- DEVMETHOD(device_resume, fbd_resume),
{ 0, 0 }
};
diff --git a/sys/dev/vt/hw/fb/vt_fb.c b/sys/dev/vt/hw/fb/vt_fb.c
index 044b641..5a0fe4f 100644
--- a/sys/dev/vt/hw/fb/vt_fb.c
+++ b/sys/dev/vt/hw/fb/vt_fb.c
@@ -53,6 +53,8 @@ static struct vt_driver vt_fb_driver = {
.vd_priority = VD_PRIORITY_GENERIC+10,
.vd_fb_ioctl = vt_fb_ioctl,
.vd_fb_mmap = vt_fb_mmap,
+ .vd_suspend = vt_fb_suspend,
+ .vd_resume = vt_fb_resume,
};
VT_DRIVER_DECLARE(vt_fb, vt_fb_driver);
@@ -450,15 +452,15 @@ vt_fb_attach(struct fb_info *info)
}
void
-vt_fb_resume(void)
+vt_fb_suspend(struct vt_device *vd)
{
- vt_resume();
+ vt_suspend(vd);
}
void
-vt_fb_suspend(void)
+vt_fb_resume(struct vt_device *vd)
{
- vt_suspend();
+ vt_resume(vd);
}
diff --git a/sys/dev/vt/hw/fb/vt_fb.h b/sys/dev/vt/hw/fb/vt_fb.h
index 43ce2b7..ac18cff 100644
--- a/sys/dev/vt/hw/fb/vt_fb.h
+++ b/sys/dev/vt/hw/fb/vt_fb.h
@@ -33,8 +33,8 @@
#define _DEV_VT_HW_FB_VT_FB_H_
/* Generic framebuffer interface call vt_fb_attach to init VT(9) */
int vt_fb_attach(struct fb_info *info);
-void vt_fb_resume(void);
-void vt_fb_suspend(void);
+void vt_fb_resume(struct vt_device *vd);
+void vt_fb_suspend(struct vt_device *vd);
vd_init_t vt_fb_init;
vd_blank_t vt_fb_blank;
diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h
index 67fcf1e..0ad8ab5 100644
--- a/sys/dev/vt/vt.h
+++ b/sys/dev/vt/vt.h
@@ -90,8 +90,6 @@ SYSCTL_INT(_kern_vt, OID_AUTO, _name, CTLFLAG_RWTUN, &vt_##_name, _default,\
struct vt_driver;
void vt_allocate(struct vt_driver *, void *);
-void vt_resume(void);
-void vt_suspend(void);
typedef unsigned int vt_axis_t;
@@ -162,6 +160,9 @@ struct vt_device {
#define VD_PASTEBUFSZ(vd) ((vd)->vd_pastebuf.vpb_bufsz)
#define VD_PASTEBUFLEN(vd) ((vd)->vd_pastebuf.vpb_len)
+void vt_resume(struct vt_device *vd);
+void vt_suspend(struct vt_device *vd);
+
/*
* Per-window terminal screen buffer.
*
@@ -314,6 +315,8 @@ typedef int vd_fb_mmap_t(struct vt_device *, vm_ooffset_t, vm_paddr_t *, int,
typedef void vd_drawrect_t(struct vt_device *, int, int, int, int, int,
term_color_t);
typedef void vd_setpixel_t(struct vt_device *, int, int, term_color_t);
+typedef void vd_suspend_t(struct vt_device *);
+typedef void vd_resume_t(struct vt_device *);
struct vt_driver {
char vd_name[16];
@@ -337,6 +340,10 @@ struct vt_driver {
/* Update display setting on vt switch. */
vd_postswitch_t *vd_postswitch;
+ /* Suspend/resume handlers. */
+ vd_suspend_t *vd_suspend;
+ vd_resume_t *vd_resume;
+
/* Priority to know which one can override */
int vd_priority;
#define VD_PRIORITY_DUMB 10
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index bf0ae1a..d700730 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -167,6 +167,8 @@ static void vt_update_static(void *);
#ifndef SC_NO_CUTPASTE
static void vt_mouse_paste(void);
#endif
+static void vt_suspend_handler(void *priv);
+static void vt_resume_handler(void *priv);
SET_DECLARE(vt_drv_set, struct vt_driver);
@@ -2552,6 +2554,12 @@ vt_upgrade(struct vt_device *vd)
vd->vd_flags |= VDF_ASYNC;
callout_reset(&vd->vd_timer, hz / VT_TIMERFREQ, vt_timer, vd);
vd->vd_timer_armed = 1;
+
+ /* Register suspend/resume handlers. */
+ EVENTHANDLER_REGISTER(power_suspend, vt_suspend_handler, vd,
+ EVENTHANDLER_PRI_ANY);
+ EVENTHANDLER_REGISTER(power_resume, vt_resume_handler, vd,
+ EVENTHANDLER_PRI_ANY);
}
VT_UNLOCK(vd);
@@ -2655,26 +2663,54 @@ vt_allocate(struct vt_driver *drv, void *softc)
termcn_cnregister(vd->vd_windows[VT_CONSWINDOW]->vw_terminal);
}
+static void
+vt_suspend_handler(void *priv)
+{
+ struct vt_device *vd;
+
+ vd = priv;
+ if (vd->vd_driver != NULL && vd->vd_driver->vd_suspend != NULL)
+ vd->vd_driver->vd_suspend(vd);
+}
+
+static void
+vt_resume_handler(void *priv)
+{
+ struct vt_device *vd;
+
+ vd = priv;
+ if (vd->vd_driver != NULL && vd->vd_driver->vd_resume != NULL)
+ vd->vd_driver->vd_resume(vd);
+}
+
void
-vt_suspend()
+vt_suspend(struct vt_device *vd)
{
+ int error;
if (vt_suspendswitch == 0)
return;
/* Save current window. */
- main_vd->vd_savedwindow = main_vd->vd_curwindow;
+ vd->vd_savedwindow = vd->vd_curwindow;
/* Ask holding process to free window and switch to console window */
- vt_proc_window_switch(main_vd->vd_windows[VT_CONSWINDOW]);
+ vt_proc_window_switch(vd->vd_windows[VT_CONSWINDOW]);
+
+ /* Wait for the window switch to complete. */
+ error = 0;
+ VT_LOCK(vd);
+ while (vd->vd_curwindow != vd->vd_windows[VT_CONSWINDOW] && error == 0)
+ error = cv_wait_sig(&vd->vd_winswitch, &vd->vd_lock);
+ VT_UNLOCK(vd);
}
void
-vt_resume()
+vt_resume(struct vt_device *vd)
{
if (vt_suspendswitch == 0)
return;
/* Switch back to saved window */
- if (main_vd->vd_savedwindow != NULL)
- vt_proc_window_switch(main_vd->vd_savedwindow);
- main_vd->vd_savedwindow = NULL;
+ if (vd->vd_savedwindow != NULL)
+ vt_proc_window_switch(vd->vd_savedwindow);
+ vd->vd_savedwindow = NULL;
}
OpenPOWER on IntegriCloud