svn commit: r277795 - in head/sys/dev: fb vt vt/hw/fb

Andriy Gapon avg at FreeBSD.org
Tue Jan 27 15:28:48 UTC 2015


Author: avg
Date: Tue Jan 27 15:28:46 2015
New Revision: 277795
URL: https://svnweb.freebsd.org/changeset/base/277795

Log:
  vt(4): Use power_{suspend,resume} event handlers to implement
  suspend/resume
  
  The goal is to avoid that the vt(4) resume happens before the video
  display is resumed. The original patch was provided by Andriy Gapon.
  
  This new patch registers the handlers in vt_upgrade(). This is done
  once, thanks to the VDF_ASYNC flag. I abused this flag because it was
  already abused by the keyboard allocation. The event handlers then call
  the backend if it provides callbacks for suspend/resume.
  
  Differential Revision:	https://reviews.freebsd.org/D1004
  On behalf of:	dumbbell
  MFC after:	2 weeks

Modified:
  head/sys/dev/fb/fbd.c
  head/sys/dev/vt/hw/fb/vt_fb.c
  head/sys/dev/vt/hw/fb/vt_fb.h
  head/sys/dev/vt/vt.h
  head/sys/dev/vt/vt_core.c

Modified: head/sys/dev/fb/fbd.c
==============================================================================
--- head/sys/dev/fb/fbd.c	Tue Jan 27 10:32:49 2015	(r277794)
+++ head/sys/dev/fb/fbd.c	Tue Jan 27 15:28:46 2015	(r277795)
@@ -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 }
 };

Modified: head/sys/dev/vt/hw/fb/vt_fb.c
==============================================================================
--- head/sys/dev/vt/hw/fb/vt_fb.c	Tue Jan 27 10:32:49 2015	(r277794)
+++ head/sys/dev/vt/hw/fb/vt_fb.c	Tue Jan 27 15:28:46 2015	(r277795)
@@ -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);
 }

Modified: head/sys/dev/vt/hw/fb/vt_fb.h
==============================================================================
--- head/sys/dev/vt/hw/fb/vt_fb.h	Tue Jan 27 10:32:49 2015	(r277794)
+++ head/sys/dev/vt/hw/fb/vt_fb.h	Tue Jan 27 15:28:46 2015	(r277795)
@@ -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;

Modified: head/sys/dev/vt/vt.h
==============================================================================
--- head/sys/dev/vt/vt.h	Tue Jan 27 10:32:49 2015	(r277794)
+++ head/sys/dev/vt/vt.h	Tue Jan 27 15:28:46 2015	(r277795)
@@ -90,8 +90,6 @@ SYSCTL_INT(_kern_vt, OID_AUTO, _name, CT
 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_devic
 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

Modified: head/sys/dev/vt/vt_core.c
==============================================================================
--- head/sys/dev/vt/vt_core.c	Tue Jan 27 10:32:49 2015	(r277794)
+++ head/sys/dev/vt/vt_core.c	Tue Jan 27 15:28:46 2015	(r277795)
@@ -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 
 	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;
 }


More information about the svn-src-head mailing list