aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2010-09-21 14:49:39 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-10-04 19:59:12 -0400
commit8ac3891b48906b38db4b153c2d0d55db2ef81aee (patch)
treea01cfeb53235f2d112e2f327e52d603b7ef67f11 /drivers/gpu/drm/nouveau
parent2730723bbc4a8b289fa536fc3555e15947da09c1 (diff)
drm/nouveau: Provide a means to have arbitrary work run on fence completion.
Signed-off-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c30
2 files changed, 33 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 9a9066f1fbcc..d4f049d42ede 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1243,6 +1243,9 @@ extern void nouveau_fence_update(struct nouveau_channel *);
1243extern int nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **, 1243extern int nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **,
1244 bool emit); 1244 bool emit);
1245extern int nouveau_fence_emit(struct nouveau_fence *); 1245extern int nouveau_fence_emit(struct nouveau_fence *);
1246extern void nouveau_fence_work(struct nouveau_fence *fence,
1247 void (*work)(void *priv, bool signalled),
1248 void *priv);
1246struct nouveau_channel *nouveau_fence_channel(struct nouveau_fence *); 1249struct nouveau_channel *nouveau_fence_channel(struct nouveau_fence *);
1247extern bool nouveau_fence_signalled(void *obj, void *arg); 1250extern bool nouveau_fence_signalled(void *obj, void *arg);
1248extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr); 1251extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr);
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 62f13189698a..fbb2c3b26239 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -39,6 +39,9 @@ struct nouveau_fence {
39 39
40 uint32_t sequence; 40 uint32_t sequence;
41 bool signalled; 41 bool signalled;
42
43 void (*work)(void *priv, bool signalled);
44 void *priv;
42}; 45};
43 46
44static inline struct nouveau_fence * 47static inline struct nouveau_fence *
@@ -78,6 +81,10 @@ nouveau_fence_update(struct nouveau_channel *chan)
78 sequence = fence->sequence; 81 sequence = fence->sequence;
79 fence->signalled = true; 82 fence->signalled = true;
80 list_del(&fence->entry); 83 list_del(&fence->entry);
84
85 if (unlikely(fence->work))
86 fence->work(fence->priv, true);
87
81 kref_put(&fence->refcount, nouveau_fence_del); 88 kref_put(&fence->refcount, nouveau_fence_del);
82 89
83 if (sequence == chan->fence.sequence_ack) 90 if (sequence == chan->fence.sequence_ack)
@@ -148,6 +155,25 @@ nouveau_fence_emit(struct nouveau_fence *fence)
148} 155}
149 156
150void 157void
158nouveau_fence_work(struct nouveau_fence *fence,
159 void (*work)(void *priv, bool signalled),
160 void *priv)
161{
162 BUG_ON(fence->work);
163
164 spin_lock(&fence->channel->fence.lock);
165
166 if (fence->signalled) {
167 work(priv, true);
168 } else {
169 fence->work = work;
170 fence->priv = priv;
171 }
172
173 spin_unlock(&fence->channel->fence.lock);
174}
175
176void
151nouveau_fence_unref(void **sync_obj) 177nouveau_fence_unref(void **sync_obj)
152{ 178{
153 struct nouveau_fence *fence = nouveau_fence(*sync_obj); 179 struct nouveau_fence *fence = nouveau_fence(*sync_obj);
@@ -268,6 +294,10 @@ nouveau_fence_channel_fini(struct nouveau_channel *chan)
268 list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) { 294 list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) {
269 fence->signalled = true; 295 fence->signalled = true;
270 list_del(&fence->entry); 296 list_del(&fence->entry);
297
298 if (unlikely(fence->work))
299 fence->work(fence->priv, false);
300
271 kref_put(&fence->refcount, nouveau_fence_del); 301 kref_put(&fence->refcount, nouveau_fence_del);
272 } 302 }
273} 303}