From owner-svn-src-all@FreeBSD.ORG Tue Jan 27 15:28:48 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 7F8EE420; Tue, 27 Jan 2015 15:28:48 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6B2C8AD3; Tue, 27 Jan 2015 15:28:48 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0RFSmaa098485; Tue, 27 Jan 2015 15:28:48 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0RFSle9098480; Tue, 27 Jan 2015 15:28:47 GMT (envelope-from avg@FreeBSD.org) Message-Id: <201501271528.t0RFSle9098480@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Tue, 27 Jan 2015 15:28:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r277795 - in head/sys/dev: fb vt vt/hw/fb X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Jan 2015 15:28:48 -0000 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; }