diff --git a/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c b/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c index de79d1491a15..f9188135428b 100644 --- a/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c +++ b/sys/external/bsd/drm2/dist/drm/i915/i915_dma.c @@ -1851,6 +1851,7 @@ out_gtt: dev_priv->gtt.base.cleanup(&dev_priv->gtt.base); out_regs: intel_uncore_fini(dev); + intel_uncore_destroy(dev); pci_iounmap(dev->pdev, dev_priv->regs); put_bridge: pci_dev_put(dev_priv->bridge_dev); @@ -1966,6 +1967,7 @@ int i915_driver_unload(struct drm_device *dev) dev_priv->gtt.base.cleanup(&dev_priv->gtt.base); intel_uncore_fini(dev); + intel_uncore_destroy(dev); if (dev_priv->regs != NULL) pci_iounmap(dev->pdev, dev_priv->regs); diff --git a/sys/external/bsd/drm2/dist/drm/i915/i915_drv.c b/sys/external/bsd/drm2/dist/drm/i915/i915_drv.c index 584630f009e7..4caf367fb528 100644 --- a/sys/external/bsd/drm2/dist/drm/i915/i915_drv.c +++ b/sys/external/bsd/drm2/dist/drm/i915/i915_drv.c @@ -427,7 +427,7 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) return true; } -static int i915_drm_freeze(struct drm_device *dev) +int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc; @@ -563,7 +563,7 @@ static void intel_resume_hotplug(struct drm_device *dev) drm_helper_hpd_irq_event(dev); } -static int i915_drm_thaw_early(struct drm_device *dev) +int i915_drm_thaw_early(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -644,15 +644,13 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) return error; } -#ifndef __NetBSD__ /* XXX freeze/thaw */ -static int i915_drm_thaw(struct drm_device *dev) +int i915_drm_thaw(struct drm_device *dev) { if (drm_core_check_feature(dev, DRIVER_MODESET)) i915_check_and_clear_faults(dev); return __i915_drm_thaw(dev, true); } -#endif static int i915_resume_early(struct drm_device *dev) { diff --git a/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h b/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h index 9a8bf1e53afc..8f2b804f44f3 100644 --- a/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h +++ b/sys/external/bsd/drm2/dist/drm/i915/i915_drv.h @@ -2158,6 +2158,10 @@ extern int i915_resume(struct drm_device *dev); extern int i915_master_create(struct drm_device *dev, struct drm_master *master); extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); +extern int i915_drm_freeze(struct drm_device *dev); +extern int i915_drm_thaw_early(struct drm_device *dev); +extern int i915_drm_thaw(struct drm_device *dev); + /* i915_params.c */ struct i915_params { int modeset; @@ -2230,6 +2234,7 @@ extern void intel_uncore_early_sanitize(struct drm_device *dev); extern void intel_uncore_init(struct drm_device *dev); extern void intel_uncore_check_errors(struct drm_device *dev); extern void intel_uncore_fini(struct drm_device *dev); +extern void intel_uncore_destroy(struct drm_device *dev); void i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, diff --git a/sys/external/bsd/drm2/dist/drm/i915/intel_uncore.c b/sys/external/bsd/drm2/dist/drm/i915/intel_uncore.c index facee561c4ec..0a7f00a4af3c 100644 --- a/sys/external/bsd/drm2/dist/drm/i915/intel_uncore.c +++ b/sys/external/bsd/drm2/dist/drm/i915/intel_uncore.c @@ -868,14 +868,16 @@ void intel_uncore_init(struct drm_device *dev) void intel_uncore_fini(struct drm_device *dev) { -#ifdef __NetBSD__ - struct drm_i915_private *const dev_priv = dev->dev_private; -#endif - /* Paranoia: make sure we have disabled everything before we exit. */ intel_uncore_sanitize(dev); intel_uncore_forcewake_reset(dev, false); +} + +void intel_uncore_destroy(struct drm_device *dev) +{ #ifdef __NetBSD__ + struct drm_i915_private *const dev_priv = dev->dev_private; + teardown_timer(&dev_priv->uncore.force_wake_timer); #endif } diff --git a/sys/external/bsd/drm2/i915drm/i915_pci.c b/sys/external/bsd/drm2/i915drm/i915_pci.c index 39e5ea3a605c..56da0263ee54 100644 --- a/sys/external/bsd/drm2/i915drm/i915_pci.c +++ b/sys/external/bsd/drm2/i915drm/i915_pci.c @@ -1,4 +1,4 @@ -/* $NetBSD: i915_pci.c,v 1.11 2014/07/16 20:56:25 riastradh Exp $ */ +/* $NetBSD: i915_pci.c,v 1.12 2014/07/16 23:25:18 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: i915_pci.c,v 1.11 2014/07/16 20:56:25 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: i915_pci.c,v 1.12 2014/07/16 23:25:18 riastradh Exp $"); #ifdef _KERNEL_OPT #include "vga.h" @@ -94,6 +94,9 @@ static int i915drmkms_match(device_t, cfdata_t, void *); static void i915drmkms_attach(device_t, device_t, void *); static int i915drmkms_detach(device_t, int); +static bool i915drmkms_suspend(device_t, const pmf_qual_t *); +static bool i915drmkms_resume(device_t, const pmf_qual_t *); + static void intel_genfb_defer_set_config(struct drm_fb_helper *); static void intel_genfb_set_config_work(struct work *, void *); static void intel_genfb_set_config(struct intel_genfb_work *); @@ -190,6 +193,10 @@ i915drmkms_attach(device_t parent, device_t self, void *aux) pci_aprint_devinfo(pa, NULL); + if (!pmf_device_register(self, &i915drmkms_suspend, + &i915drmkms_resume)) + aprint_error_dev(self, "unable to establish power handler\n"); + SIMPLEQ_INIT(&sc->sc_genfb_work); /* XXX errno Linux->NetBSD */ @@ -229,19 +236,58 @@ i915drmkms_detach(device_t self, int flags) return error; if (sc->sc_genfb_wq == NULL) - return 0; + goto out; workqueue_destroy(sc->sc_genfb_wq); if (sc->sc_drm_dev == NULL) - return 0; + goto out; /* XXX errno Linux->NetBSD */ error = -drm_pci_detach(sc->sc_drm_dev, flags); if (error) return error; + sc->sc_drm_dev = NULL; +out: pmf_device_deregister(self); return 0; } +static bool +i915drmkms_suspend(device_t self, const pmf_qual_t *qual) +{ + struct i915drmkms_softc *const sc = device_private(self); + struct drm_device *const dev = sc->sc_drm_dev; + int ret; + + if (dev == NULL) + return true; + + ret = i915_drm_freeze(dev); + if (ret) + return false; + + return true; +} + +static bool +i915drmkms_resume(device_t self, const pmf_qual_t *qual) +{ + struct i915drmkms_softc *const sc = device_private(self); + struct drm_device *const dev = sc->sc_drm_dev; + int ret; + + if (dev == NULL) + return true; + + ret = i915_drm_thaw_early(dev); + if (ret) + return false; + ret = i915_drm_thaw(dev); + if (ret) + return false; + + return true; +} + int intel_genfb_attach(struct drm_device *dev, struct drm_fb_helper *helper, const struct drm_fb_helper_surface_size *sizes)