diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-09-28 17:29:57 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-09-28 17:29:57 +0000 |
commit | 581ca1c68542b0da7cc84c10d30e5da60df1a4b2 (patch) | |
tree | 64f80842a796d7eb396dad596981f5695a3f506e | |
parent | 1dfa6daa1e242f5ab4c1bf7ed4526803ef098402 (diff) |
The Linux code that handles the DPMS mode for inteldrm(4) can sleep now.
Adopt the approach taken by radeondrm(4) and hand the "burner" work off
to a task.
Avoids the panic reported by Gerald Hanuer, who also tested this fix.
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.c | 29 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.h | 5 |
2 files changed, 26 insertions, 8 deletions
diff --git a/sys/dev/pci/drm/i915/i915_drv.c b/sys/dev/pci/drm/i915/i915_drv.c index 1f70e0a123a..fc84f332489 100644 --- a/sys/dev/pci/drm/i915/i915_drv.c +++ b/sys/dev/pci/drm/i915/i915_drv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: i915_drv.c,v 1.92 2015/09/28 06:47:23 kettenis Exp $ */ +/* $OpenBSD: i915_drv.c,v 1.93 2015/09/28 17:29:56 kettenis Exp $ */ /* * Copyright (c) 2008-2009 Owain G. Ainsworth <oga@openbsd.org> * @@ -966,6 +966,7 @@ int inteldrm_load_font(void *, void *, struct wsdisplay_font *); int inteldrm_list_font(void *, struct wsdisplay_font *); int inteldrm_getchar(void *, int, int, struct wsdisplay_charcell *); void inteldrm_burner(void *, u_int, u_int); +void inteldrm_burner_cb(void *); struct wsscreen_descr inteldrm_stdscreen = { "std", @@ -1140,19 +1141,32 @@ void inteldrm_burner(void *v, u_int on, u_int flags) { struct inteldrm_softc *dev_priv = v; - struct drm_fb_helper *helper = &dev_priv->fbdev->helper; - int dpms_mode; + + task_del(systq, &dev_priv->burner_task); if (on) - dpms_mode = DRM_MODE_DPMS_ON; + dev_priv->burner_dpms_mode = DRM_MODE_DPMS_ON; else { if (flags & WSDISPLAY_BURN_VBLANK) - dpms_mode = DRM_MODE_DPMS_OFF; + dev_priv->burner_dpms_mode = DRM_MODE_DPMS_OFF; else - dpms_mode = DRM_MODE_DPMS_STANDBY; + dev_priv->burner_dpms_mode = DRM_MODE_DPMS_STANDBY; } - drm_fb_helper_dpms(helper, dpms_mode); + /* + * Setting the DPMS mode may sleep while waiting for the display + * to come back on so hand things off to a taskq. + */ + task_add(systq, &dev_priv->burner_task); +} + +void +inteldrm_burner_cb(void *arg1) +{ + struct inteldrm_softc *dev_priv = arg1; + struct drm_fb_helper *helper = &dev_priv->fbdev->helper; + + drm_fb_helper_dpms(helper, dev_priv->burner_dpms_mode); } int @@ -1448,6 +1462,7 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux) rasops_init(ri, 160, 160); task_set(&dev_priv->switchtask, inteldrm_doswitch, dev_priv); + task_set(&dev_priv->burner_task, inteldrm_burner_cb, dev_priv); inteldrm_stdscreen.capabilities = ri->ri_caps; inteldrm_stdscreen.nrows = ri->ri_rows; diff --git a/sys/dev/pci/drm/i915/i915_drv.h b/sys/dev/pci/drm/i915/i915_drv.h index da813eef5c8..a0241012474 100644 --- a/sys/dev/pci/drm/i915/i915_drv.h +++ b/sys/dev/pci/drm/i915/i915_drv.h @@ -1,4 +1,4 @@ -/* $OpenBSD: i915_drv.h,v 1.68 2015/09/26 11:17:15 kettenis Exp $ */ +/* $OpenBSD: i915_drv.h,v 1.69 2015/09/28 17:29:56 kettenis Exp $ */ /* i915_drv.h -- Private header for the I915 driver -*- linux-c -*- */ /* @@ -1466,6 +1466,9 @@ typedef struct inteldrm_softc { struct task switchtask; struct rasops_info ro; + struct task burner_task; + int burner_dpms_mode; + struct backlight_device { struct intel_connector *connector; struct { |