summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2015-09-28 17:29:57 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2015-09-28 17:29:57 +0000
commit581ca1c68542b0da7cc84c10d30e5da60df1a4b2 (patch)
tree64f80842a796d7eb396dad596981f5695a3f506e /sys/dev/pci
parent1dfa6daa1e242f5ab4c1bf7ed4526803ef098402 (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.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/drm/i915/i915_drv.c29
-rw-r--r--sys/dev/pci/drm/i915/i915_drv.h5
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 {