MFC r277795,278849: vt(4): Use power_{suspend,resume} event handlers

This commit is contained in:
avg 2015-05-11 08:00:16 +00:00
parent a8e9a4b88b
commit 2413b4098a
5 changed files with 66 additions and 34 deletions

View File

@ -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 }
};

View File

@ -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);
@ -441,15 +443,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);
}

View File

@ -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;

View File

@ -91,8 +91,6 @@ TUNABLE_INT("kern.vt." #_name, &vt_##_name);
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

View File

@ -166,6 +166,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);
@ -2507,6 +2509,7 @@ vt_upgrade(struct vt_device *vd)
{
struct vt_window *vw;
unsigned int i;
int register_handlers;
if (!vty_enabled(VTY_VT))
return;
@ -2535,6 +2538,7 @@ vt_upgrade(struct vt_device *vd)
if (vd->vd_curwindow == NULL)
vd->vd_curwindow = vd->vd_windows[VT_CONSWINDOW];
register_handlers = 0;
if (!(vd->vd_flags & VDF_ASYNC)) {
/* Attach keyboard. */
vt_allocate_keyboard(vd);
@ -2546,12 +2550,21 @@ 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_handlers = 1;
}
VT_UNLOCK(vd);
/* Refill settings with new sizes. */
vt_resize(vd);
if (register_handlers) {
/* 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);
}
}
static void
@ -2649,26 +2662,54 @@ vt_allocate(struct vt_driver *drv, void *softc)
termcn_cnregister(vd->vd_windows[VT_CONSWINDOW]->vw_terminal);
}
void
vt_suspend()
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(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;
}