summaryrefslogtreecommitdiff
path: root/linux-core/drm_lock.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-08-21 20:30:19 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-08-21 20:30:19 +0200
commit42c2cfcf7d5730a2961d425228e042f533b312fa (patch)
tree50cd98133445a2e3af6309f35c7bdf7af5603eaa /linux-core/drm_lock.c
parent11f9e404fb66927146de30227fa05c5485aa1726 (diff)
Generic DRM support base-class support for user-space objects, like
fence objects and buffer objects: Refcounting, Inter-process sharing, Synchronization Destruction.
Diffstat (limited to 'linux-core/drm_lock.c')
-rw-r--r--linux-core/drm_lock.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/linux-core/drm_lock.c b/linux-core/drm_lock.c
index a268d8ee..c12e4897 100644
--- a/linux-core/drm_lock.c
+++ b/linux-core/drm_lock.c
@@ -308,3 +308,60 @@ static int drm_notifier(void *priv)
} while (prev != old);
return 0;
}
+
+/*
+ * Can be used by drivers to take the hardware lock if necessary.
+ * (Waiting for idle before reclaiming buffers etc.)
+ */
+
+int drm_i_have_hw_lock(struct file *filp)
+{
+ DRM_DEVICE;
+
+ return (priv->lock_count && dev->lock.hw_lock &&
+ _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
+ dev->lock.filp == filp);
+}
+
+EXPORT_SYMBOL(drm_i_have_hw_lock);
+
+int drm_kernel_take_hw_lock(struct file *filp)
+{
+ DRM_DEVICE;
+
+ int ret = 0;
+
+ if (!drm_i_have_hw_lock(filp)) {
+
+ DECLARE_WAITQUEUE(entry, current);
+
+ add_wait_queue(&dev->lock.lock_queue, &entry);
+ for (;;) {
+ __set_current_state(TASK_INTERRUPTIBLE);
+ if (!dev->lock.hw_lock) {
+ /* Device has been unregistered */
+ ret = -EINTR;
+ break;
+ }
+ if (drm_lock_take(&dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ dev->lock.filp = filp;
+ dev->lock.lock_time = jiffies;
+ atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
+ break; /* Got lock */
+ }
+ /* Contention */
+ schedule();
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+ }
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&dev->lock.lock_queue, &entry);
+ }
+ return ret;
+}
+
+EXPORT_SYMBOL(drm_kernel_take_hw_lock);
+