From 9a61b94f9565e481283736336aa4b886384b195f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 17 Apr 2011 06:38:35 +0100 Subject: [PATCH] drm/i915/dp: Be paranoid in case we disable a DP before it is attached Given that the hardware may be left in a random condition by the BIOS, it is conceivable that we then attempt to clear the DP_PIPEB_SELECT bit without us ever enabling/attaching the DP encoder to a pipe. Thus causing a NULL deference when we attempt to wait for a vblank on that crtc. Reported-by: Bryan Chris References: https://bugs.freedesktop.org/show_bug.cgi?id=36314 Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/intel_dp.c | 3 +-- drivers/gpu/drm/i915/intel_drv.h | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0daefca..819afca 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1470,7 +1470,6 @@ intel_dp_link_down(struct intel_dp *intel_dp) if (!HAS_PCH_CPT(dev) && I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { - struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); /* Hardware workaround: leaving our transcoder select * set to transcoder B while it's off will prevent the * corresponding HDMI output on transcoder A. @@ -1485,7 +1484,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) /* Changes to enable or select take place the vblank * after being written. */ - intel_wait_for_vblank(dev, intel_crtc->pipe); + intel_wait_for_crtc_vblank_safe(intel_dp->base.base.crtc); } I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f5b0d83..aeb1b98 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -290,6 +290,13 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); +static inline void intel_wait_for_crtc_vblank_safe(struct drm_crtc *crtc) +{ + if (crtc) + intel_wait_for_vblank(crtc->dev, to_intel_crtc(crtc)->pipe); + else + msleep(50); +} extern void intel_wait_for_pipe_off(struct drm_device *dev, int pipe); extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, struct drm_connector *connector, -- 1.7.4.1