#include <core/event.h>
 #include <nvif/unpack.h>
 #include <nvif/class.h>
+#include <nvif/event.h>
 
 #include <engine/dmaobj.h>
 #include <engine/fifo.h>
        iowrite32_native(data, chan->user + addr);
 }
 
+int
+nouveau_fifo_uevent_ctor(void *data, u32 size, struct nvkm_notify *notify)
+{
+       union {
+               struct nvif_notify_uevent_req none;
+       } *req = data;
+       int ret;
+
+       if (nvif_unvers(req->none)) {
+               notify->size  = sizeof(struct nvif_notify_uevent_rep);
+               notify->types = 1;
+               notify->index = 0;
+       }
+
+       return ret;
+}
+
+void
+nouveau_fifo_uevent(struct nouveau_fifo *fifo)
+{
+       struct nvif_notify_uevent_rep rep = {
+       };
+       nvkm_event_send(&fifo->uevent, 1, 0, &rep, sizeof(rep));
+}
+
+int
+_nouveau_fifo_channel_ntfy(struct nouveau_object *object, u32 type,
+                          struct nvkm_event **event)
+{
+       struct nouveau_fifo *fifo = (void *)object->engine;
+       switch (type) {
+       case G82_CHANNEL_DMA_V0_NTFY_UEVENT:
+               if (nv_mclass(object) >= G82_CHANNEL_DMA) {
+                       *event = &fifo->uevent;
+                       return 0;
+               }
+               break;
+       default:
+               break;
+       }
+       return -EINVAL;
+}
+
 static int
 nouveau_fifo_chid(struct nouveau_fifo *priv, struct nouveau_object *object)
 {
 
        .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
+       .ntfy = _nouveau_fifo_channel_ntfy
 };
 
 static struct nouveau_oclass
                        }
 
                        if (status & 0x40000000) {
-                               nvkm_event_send(&priv->base.uevent, 1, 0, NULL, 0);
+                               nouveau_fifo_uevent(&priv->base);
                                nv_wr32(priv, 0x002100, 0x40000000);
                                status &= ~0x40000000;
                        }
 
        .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
+       .ntfy = _nouveau_fifo_channel_ntfy
 };
 
 static struct nouveau_oclass
 
        .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
+       .ntfy = _nouveau_fifo_channel_ntfy
 };
 
 static struct nouveau_oclass
 
        .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
+       .ntfy = _nouveau_fifo_channel_ntfy
 };
 
 static struct nouveau_oclass
 
        .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
+       .ntfy = _nouveau_fifo_channel_ntfy
 };
 
 static struct nouveau_ofuncs
        .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
+       .ntfy = _nouveau_fifo_channel_ntfy
 };
 
 static struct nouveau_oclass
 
        .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
+       .ntfy = _nouveau_fifo_channel_ntfy
 };
 
 static struct nouveau_ofuncs
        .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
+       .ntfy = _nouveau_fifo_channel_ntfy
 };
 
 static struct nouveau_oclass
        nv_mask(fifo, 0x002140, 0x40000000, 0x00000000);
 }
 
-static int
-nv84_fifo_uevent_ctor(void *data, u32 size, struct nvkm_notify *notify)
-{
-       if (size == 0) {
-               notify->size  = 0;
-               notify->types = 1;
-               notify->index = 0;
-               return 0;
-       }
-       return -ENOSYS;
-}
-
 static const struct nvkm_event_func
 nv84_fifo_uevent_func = {
-       .ctor = nv84_fifo_uevent_ctor,
+       .ctor = nouveau_fifo_uevent_ctor,
        .init = nv84_fifo_uevent_init,
        .fini = nv84_fifo_uevent_fini,
 };
 
        .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
+       .ntfy = _nouveau_fifo_channel_ntfy
 };
 
 static struct nouveau_oclass
        for (unkn = 0; unkn < 8; unkn++) {
                u32 ints = (intr >> (unkn * 0x04)) & inte;
                if (ints & 0x1) {
-                       nvkm_event_send(&priv->base.uevent, 1, 0, NULL, 0);
+                       nouveau_fifo_uevent(&priv->base);
                        ints &= ~1;
                }
                if (ints) {
        nv_mask(fifo, 0x002140, 0x80000000, 0x00000000);
 }
 
-static int
-nvc0_fifo_uevent_ctor(void *data, u32 size, struct nvkm_notify *notify)
-{
-       if (size == 0) {
-               notify->size  = 0;
-               notify->types = 1;
-               notify->index = 0;
-               return 0;
-       }
-       return -ENOSYS;
-}
-
 static const struct nvkm_event_func
 nvc0_fifo_uevent_func = {
-       .ctor = nvc0_fifo_uevent_ctor,
+       .ctor = nouveau_fifo_uevent_ctor,
        .init = nvc0_fifo_uevent_init,
        .fini = nvc0_fifo_uevent_fini,
 };
 
        .map  = _nouveau_fifo_channel_map,
        .rd32 = _nouveau_fifo_channel_rd32,
        .wr32 = _nouveau_fifo_channel_wr32,
+       .ntfy = _nouveau_fifo_channel_ntfy
 };
 
 static struct nouveau_oclass
 static void
 nve0_fifo_intr_engine(struct nve0_fifo_priv *priv)
 {
-       nvkm_event_send(&priv->base.uevent, 1, 0, NULL, 0);
+       nouveau_fifo_uevent(&priv->base);
 }
 
 static void
        nv_mask(fifo, 0x002140, 0x80000000, 0x00000000);
 }
 
-static int
-nve0_fifo_uevent_ctor(void *data, u32 size, struct nvkm_notify *notify)
-{
-       if (size == 0) {
-               notify->size  = 0;
-               notify->types = 1;
-               notify->index = 0;
-               return 0;
-       }
-       return -ENOSYS;
-}
-
 static const struct nvkm_event_func
 nve0_fifo_uevent_func = {
-       .ctor = nve0_fifo_uevent_ctor,
+       .ctor = nouveau_fifo_uevent_ctor,
        .init = nve0_fifo_uevent_init,
        .fini = nve0_fifo_uevent_fini,
 };
 
 #include <core/namedb.h>
 #include <core/gpuobj.h>
 #include <core/engine.h>
+#include <core/event.h>
 
 struct nouveau_fifo_chan {
        struct nouveau_namedb base;
 int  _nouveau_fifo_channel_map(struct nouveau_object *, u64 *, u32 *);
 u32  _nouveau_fifo_channel_rd32(struct nouveau_object *, u64);
 void _nouveau_fifo_channel_wr32(struct nouveau_object *, u64, u32);
+int  _nouveau_fifo_channel_ntfy(struct nouveau_object *, u32, struct nvkm_event **);
 
 struct nouveau_fifo_base {
        struct nouveau_gpuobj base;
 extern struct nouveau_oclass *gk20a_fifo_oclass;
 extern struct nouveau_oclass *nv108_fifo_oclass;
 
+int  nouveau_fifo_uevent_ctor(void *, u32, struct nvkm_notify *);
+void nouveau_fifo_uevent(struct nouveau_fifo *);
+
 void nv04_fifo_intr(struct nouveau_subdev *);
 int  nv04_fifo_context_attach(struct nouveau_object *, struct nouveau_object *);
 
 
 #include <linux/ktime.h>
 #include <linux/hrtimer.h>
 
+#include <nvif/notify.h>
+#include <nvif/event.h>
+
 #include "nouveau_drm.h"
 #include "nouveau_dma.h"
 #include "nouveau_fence.h"
 
 struct nouveau_fence_wait {
        struct nouveau_fence_priv *priv;
-       struct nvkm_notify notify;
+       struct nvif_notify notify;
 };
 
 static int
-nouveau_fence_wait_uevent_handler(struct nvkm_notify *notify)
+nouveau_fence_wait_uevent_handler(struct nvif_notify *notify)
 {
        struct nouveau_fence_wait *wait =
                container_of(notify, typeof(*wait), notify);
        wake_up_all(&wait->priv->waiting);
-       return NVKM_NOTIFY_KEEP;
+       return NVIF_NOTIFY_KEEP;
 }
 
 static int
 
 {
        struct nouveau_channel *chan = fence->channel;
-       struct nouveau_fifo *pfifo = nvkm_fifo(chan->device);
        struct nouveau_fence_priv *priv = chan->drm->fence;
        struct nouveau_fence_wait wait = { .priv = priv };
        int ret = 0;
 
-       ret = nvkm_notify_init(&pfifo->uevent,
+       ret = nvif_notify_init(chan->object, NULL,
                               nouveau_fence_wait_uevent_handler, false,
-                              NULL, 0, 0, &wait.notify);
+                              G82_CHANNEL_DMA_V0_NTFY_UEVENT,
+                              &(struct nvif_notify_uevent_req) {
+                              },
+                              sizeof(struct nvif_notify_uevent_req),
+                              sizeof(struct nvif_notify_uevent_rep),
+                              &wait.notify);
        if (ret)
                return ret;
 
-       nvkm_notify_get(&wait.notify);
+       nvif_notify_get(&wait.notify);
 
        if (fence->timeout) {
                unsigned long timeout = fence->timeout - jiffies;
                }
        }
 
-       nvkm_notify_fini(&wait.notify);
+       nvif_notify_fini(&wait.notify);
        if (unlikely(ret < 0))
                return ret;
 
 
        __u64 offset;
 };
 
+#define G82_CHANNEL_DMA_V0_NTFY_UEVENT                                     0x00
 
 /*******************************************************************************
  * GPFIFO channels
 
        __u8  pad02[6];
 };
 
+struct nvif_notify_uevent_req {
+       /* nvif_notify_req ... */
+};
+
+struct nvif_notify_uevent_rep {
+       /* nvif_notify_rep ... */
+};
+
 #endif