|
@@ -129,6 +129,90 @@ void drm_modeset_unlock_all(struct drm_device *dev)
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(drm_modeset_unlock_all);
|
|
EXPORT_SYMBOL(drm_modeset_unlock_all);
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * drm_modeset_lock_crtc - lock crtc with hidden acquire ctx
|
|
|
|
+ * @crtc: drm crtc
|
|
|
|
+ *
|
|
|
|
+ * This function locks the given crtc using a hidden acquire context. This is
|
|
|
|
+ * necessary so that drivers internally using the atomic interfaces can grab
|
|
|
|
+ * further locks with the lock acquire context.
|
|
|
|
+ */
|
|
|
|
+void drm_modeset_lock_crtc(struct drm_crtc *crtc)
|
|
|
|
+{
|
|
|
|
+ struct drm_modeset_acquire_ctx *ctx;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
|
|
|
+ if (WARN_ON(!ctx))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ drm_modeset_acquire_init(ctx, 0);
|
|
|
|
+
|
|
|
|
+retry:
|
|
|
|
+ ret = drm_modeset_lock(&crtc->mutex, ctx);
|
|
|
|
+ if (ret)
|
|
|
|
+ goto fail;
|
|
|
|
+
|
|
|
|
+ WARN_ON(crtc->acquire_ctx);
|
|
|
|
+
|
|
|
|
+ /* now we hold the locks, so now that it is safe, stash the
|
|
|
|
+ * ctx for drm_modeset_unlock_crtc():
|
|
|
|
+ */
|
|
|
|
+ crtc->acquire_ctx = ctx;
|
|
|
|
+
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+fail:
|
|
|
|
+ if (ret == -EDEADLK) {
|
|
|
|
+ drm_modeset_backoff(ctx);
|
|
|
|
+ goto retry;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(drm_modeset_lock_crtc);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * drm_modeset_legacy_acquire_ctx - find acquire ctx for legacy ioctls
|
|
|
|
+ * crtc: drm crtc
|
|
|
|
+ *
|
|
|
|
+ * Legacy ioctl operations like cursor updates or page flips only have per-crtc
|
|
|
|
+ * locking, and store the acquire ctx in the corresponding crtc. All other
|
|
|
|
+ * legacy operations take all locks and use a global acquire context. This
|
|
|
|
+ * function grabs the right one.
|
|
|
|
+ */
|
|
|
|
+struct drm_modeset_acquire_ctx *
|
|
|
|
+drm_modeset_legacy_acquire_ctx(struct drm_crtc *crtc)
|
|
|
|
+{
|
|
|
|
+ if (crtc->acquire_ctx)
|
|
|
|
+ return crtc->acquire_ctx;
|
|
|
|
+
|
|
|
|
+ WARN_ON(!crtc->dev->mode_config.acquire_ctx);
|
|
|
|
+
|
|
|
|
+ return crtc->dev->mode_config.acquire_ctx;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(drm_modeset_legacy_acquire_ctx);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * drm_modeset_unlock_crtc - drop crtc lock
|
|
|
|
+ * @crtc: drm crtc
|
|
|
|
+ *
|
|
|
|
+ * This drops the crtc lock acquire with drm_modeset_lock_crtc() and all other
|
|
|
|
+ * locks acquired through the hidden context.
|
|
|
|
+ */
|
|
|
|
+void drm_modeset_unlock_crtc(struct drm_crtc *crtc)
|
|
|
|
+{
|
|
|
|
+ struct drm_modeset_acquire_ctx *ctx = crtc->acquire_ctx;
|
|
|
|
+
|
|
|
|
+ if (WARN_ON(!ctx))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ crtc->acquire_ctx = NULL;
|
|
|
|
+ drm_modeset_drop_locks(ctx);
|
|
|
|
+ drm_modeset_acquire_fini(ctx);
|
|
|
|
+
|
|
|
|
+ kfree(ctx);
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(drm_modeset_unlock_crtc);
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked
|
|
* drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked
|
|
* @dev: device
|
|
* @dev: device
|