summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_atomic_helper.c
diff options
context:
space:
mode:
authorDaniel Vetter2017-03-21 17:41:49 +0100
committerDaniel Vetter2017-03-27 09:43:58 +0200
commit18dddadc78c91a91b546acc48506c24f5f840c4f (patch)
tree8a11353a9b124e1014f671dc6b47d7df9eab4ad0 /drivers/gpu/drm/drm_atomic_helper.c
parentdrm/tinydrm: Fix drm_driver.fops.owner (diff)
downloadkernel-qcow2-linux-18dddadc78c91a91b546acc48506c24f5f840c4f.tar.gz
kernel-qcow2-linux-18dddadc78c91a91b546acc48506c24f5f840c4f.tar.xz
kernel-qcow2-linux-18dddadc78c91a91b546acc48506c24f5f840c4f.zip
drm/atomic: Introduce drm_atomic_helper_shutdown
The trouble here is that it does multiple atomic commits under one drm_modeset_lock_all, which breaks the behind-the-scenes acquire context magic that function pulls off. It's much better to have one overall atomic commit. That we still have multiple atomic commits prevents us from adding some pretty useful debug checks to the atomic machinery. Hence it is really a bad idea to call the legacy drm_crtc_force_disable_all() function. There's 2 atomic drivers using this still, nouveau and tinydrm. To fix this, introduce a new drm_atomic_helper_shutdown() by extracting the code from i915. While at it improve kernel-doc and catch future offenders by sprinkling a WARN_ON into the legacy function. We should probably move those into the legacy modeset helpers, too ... v2: Make it compile on arm drivers too (Noralf). v3: Correct kerneldoc to point at _disable_all(). Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Acked-by: Noralf Trønnes <noralf@tronnes.org> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Noralf Trønnes <noralf@tronnes.org> Cc: Ben Skeggs <bskeggs@redhat.com> Tested-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170321164149.31531-1-daniel.vetter@ffwll.ch
Diffstat (limited to 'drivers/gpu/drm/drm_atomic_helper.c')
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 4e26b73bb0d5..c3ace44e1c8e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2443,7 +2443,8 @@ commit:
* that they are connected to.
*
* This is used for example in suspend/resume to disable all currently active
- * functions when suspending.
+ * functions when suspending. If you just want to shut down everything at e.g.
+ * driver unload, look at drm_atomic_helper_shutdown().
*
* Note that if callers haven't already acquired all modeset locks this might
* return -EDEADLK, which must be handled by calling drm_modeset_backoff().
@@ -2452,7 +2453,8 @@ commit:
* 0 on success or a negative error code on failure.
*
* See also:
- * drm_atomic_helper_suspend(), drm_atomic_helper_resume()
+ * drm_atomic_helper_suspend(), drm_atomic_helper_resume() and
+ * drm_atomic_helper_shutdown().
*/
int drm_atomic_helper_disable_all(struct drm_device *dev,
struct drm_modeset_acquire_ctx *ctx)
@@ -2517,6 +2519,42 @@ free:
EXPORT_SYMBOL(drm_atomic_helper_disable_all);
/**
+ * drm_atomic_helper_shutdown - shutdown all CRTC
+ * @dev: DRM device
+ *
+ * This shuts down all CRTC, which is useful for driver unloading. Shutdown on
+ * suspend should instead be handled with drm_atomic_helper_suspend(), since
+ * that also takes a snapshot of the modeset state to be restored on resume.
+ *
+ * This is just a convenience wrapper around drm_atomic_helper_disable_all(),
+ * and it is the atomic version of drm_crtc_force_disable_all().
+ */
+void drm_atomic_helper_shutdown(struct drm_device *dev)
+{
+ struct drm_modeset_acquire_ctx ctx;
+ int ret;
+
+ drm_modeset_acquire_init(&ctx, 0);
+ while (1) {
+ ret = drm_modeset_lock_all_ctx(dev, &ctx);
+ if (!ret)
+ ret = drm_atomic_helper_disable_all(dev, &ctx);
+
+ if (ret != -EDEADLK)
+ break;
+
+ drm_modeset_backoff(&ctx);
+ }
+
+ if (ret)
+ DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+}
+EXPORT_SYMBOL(drm_atomic_helper_shutdown);
+
+/**
* drm_atomic_helper_suspend - subsystem-level suspend helper
* @dev: DRM device
*