summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_tv.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2014-08-11 14:15:35 +0400
committerJani Nikula <jani.nikula@intel.com>2014-08-18 11:42:40 +0400
commit208bf9fdcd3575aa4a5d48b3e0295f7cdaf6fc44 (patch)
treeb33603d0c3129b59cc5b3d695e3bee8ea9d06354 /drivers/gpu/drm/i915/intel_tv.c
parent7d1311b93e58ed55f3a31cc8f94c4b8fe988a2b9 (diff)
downloadlinux-208bf9fdcd3575aa4a5d48b3e0295f7cdaf6fc44.tar.xz
drm/i915: Fix locking for intel_enable_pipe_a()
intel_enable_pipe_a() gets called with all the modeset locks already held (by drm_modeset_lock_all()), so trying to grab the same locks using another drm_modeset_acquire_ctx is going to fail miserably. Move most of the drm_modeset_acquire_ctx handling (init/drop/fini) out from intel_{get,release}_load_detect_pipe() into the callers (intel_{crt,tv}_detect()). Only the actual locking and backoff handling is left in intel_get_load_detect_pipe(). And in intel_enable_pipe_a() we just share the mode_config.acquire_ctx from drm_modeset_lock_all() which is already holding all the relevant locks. It's perfectly legal to lock the same ww_mutex multiple times using the same ww_acquire_ctx. drm_modeset_lock() will convert the returned -EALREADY into 0, so the caller doesn't need to do antyhing special. Fixes a hang on resume on my 830. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: stable@vger.kernel.org Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_tv.c')
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index e211eef4b7e4..32186a656816 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1323,11 +1323,16 @@ intel_tv_detect(struct drm_connector *connector, bool force)
struct intel_load_detect_pipe tmp;
struct drm_modeset_acquire_ctx ctx;
+ drm_modeset_acquire_init(&ctx, 0);
+
if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) {
type = intel_tv_detect_type(intel_tv, connector);
- intel_release_load_detect_pipe(connector, &tmp, &ctx);
+ intel_release_load_detect_pipe(connector, &tmp);
} else
return connector_status_unknown;
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
} else
return connector->status;