diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 20:10:20 +0200 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-08-09 21:13:02 +0200 |
commit | 79ca27706a034b683196c85f5c6901b78e5ab8f0 (patch) | |
tree | c06ff32b983e4456b3af679288dad97bfe79cfe9 /drivers/gpu/drm/nouveau/nouveau_fence.c | |
parent | drm/nouveau/core: move handle-based object apis to handle.c (diff) | |
download | linux-79ca27706a034b683196c85f5c6901b78e5ab8f0.tar.xz linux-79ca27706a034b683196c85f5c6901b78e5ab8f0.zip |
drm/nouveau/core: rework event interface
This is a lot of prep-work for being able to send event notifications
back to userspace. Events now contain data, rather than a "something
just happened" signal.
Handler data is now embedded into a containing structure, rather than
being kmalloc()'d, and can optionally have the notify routine handled
in a workqueue.
Various races between suspend/unload with display HPD/DP IRQ handlers
automagically solved as a result.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_fence.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fence.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index ab5ea3b0d666..c5efe25d06f1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -165,12 +165,18 @@ nouveau_fence_done(struct nouveau_fence *fence) return !fence->channel; } +struct nouveau_fence_wait { + struct nouveau_fence_priv *priv; + struct nvkm_notify notify; +}; + static int -nouveau_fence_wait_uevent_handler(void *data, u32 type, int index) +nouveau_fence_wait_uevent_handler(struct nvkm_notify *notify) { - struct nouveau_fence_priv *priv = data; - wake_up_all(&priv->waiting); - return NVKM_EVENT_KEEP; + struct nouveau_fence_wait *wait = + container_of(notify, typeof(*wait), notify); + wake_up_all(&wait->priv->waiting); + return NVKM_NOTIFY_KEEP; } static int @@ -180,16 +186,16 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) struct nouveau_channel *chan = fence->channel; struct nouveau_fifo *pfifo = nouveau_fifo(chan->drm->device); struct nouveau_fence_priv *priv = chan->drm->fence; - struct nouveau_eventh *handler; + struct nouveau_fence_wait wait = { .priv = priv }; int ret = 0; - ret = nouveau_event_new(pfifo->uevent, 1, 0, - nouveau_fence_wait_uevent_handler, - priv, &handler); + ret = nvkm_notify_init(&pfifo->uevent, + nouveau_fence_wait_uevent_handler, false, + NULL, 0, 0, &wait.notify); if (ret) return ret; - nouveau_event_get(handler); + nvkm_notify_get(&wait.notify); if (fence->timeout) { unsigned long timeout = fence->timeout - jiffies; @@ -221,7 +227,7 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) } } - nouveau_event_ref(NULL, &handler); + nvkm_notify_fini(&wait.notify); if (unlikely(ret < 0)) return ret; |