summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/via/via_dri1.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/via/via_dri1.c')
-rw-r--r--drivers/gpu/drm/via/via_dri1.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/drivers/gpu/drm/via/via_dri1.c b/drivers/gpu/drm/via/via_dri1.c
index 3ebe17649ec2..4c5517330110 100644
--- a/drivers/gpu/drm/via/via_dri1.c
+++ b/drivers/gpu/drm/via/via_dri1.c
@@ -5,7 +5,8 @@
* Copyright 2006 Tungsten Graphics Inc., Bismarck, ND., USA.
* Copyright 2004 Digeo, Inc., Palo Alto, CA, U.S.A. All Rights Reserved.
* Copyright 2004 The Unichrome project. All Rights Reserved.
- *
+ * Copyright 2005 Thomas Hellstrom. All Rights Reserved.
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
@@ -76,6 +77,69 @@ struct via_memblock {
struct list_head owner_list;
};
+static void via_init_futex(drm_via_private_t *dev_priv)
+{
+ unsigned int i;
+
+ DRM_DEBUG("\n");
+
+ for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
+ init_waitqueue_head(&(dev_priv->decoder_queue[i]));
+ XVMCLOCKPTR(dev_priv->sarea_priv, i)->lock = 0;
+ }
+}
+
+static void via_cleanup_futex(drm_via_private_t *dev_priv)
+{
+}
+
+static void via_release_futex(drm_via_private_t *dev_priv, int context)
+{
+ unsigned int i;
+ volatile int *lock;
+
+ if (!dev_priv->sarea_priv)
+ return;
+
+ for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
+ lock = (volatile int *)XVMCLOCKPTR(dev_priv->sarea_priv, i);
+ if ((_DRM_LOCKING_CONTEXT(*lock) == context)) {
+ if (_DRM_LOCK_IS_HELD(*lock)
+ && (*lock & _DRM_LOCK_CONT)) {
+ wake_up(&(dev_priv->decoder_queue[i]));
+ }
+ *lock = 0;
+ }
+ }
+}
+
+static int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ drm_via_futex_t *fx = data;
+ volatile int *lock;
+ drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+ drm_via_sarea_t *sAPriv = dev_priv->sarea_priv;
+ int ret = 0;
+
+ DRM_DEBUG("\n");
+
+ if (fx->lock >= VIA_NR_XVMC_LOCKS)
+ return -EFAULT;
+
+ lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock);
+
+ switch (fx->func) {
+ case VIA_FUTEX_WAIT:
+ VIA_WAIT_ON(ret, dev_priv->decoder_queue[fx->lock],
+ (fx->ms / 10) * (HZ / 100), *lock != fx->val);
+ return ret;
+ case VIA_FUTEX_WAKE:
+ wake_up(&(dev_priv->decoder_queue[fx->lock]));
+ return 0;
+ }
+ return 0;
+}
+
static int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_agp_t *agp = data;