diff options
author | 2014-08-10 04:10:20 +1000 | |
---|---|---|
committer | 2014-08-10 05:13:02 +1000 | |
commit | 79ca27706a034b683196c85f5c6901b78e5ab8f0 (patch) | |
tree | c06ff32b983e4456b3af679288dad97bfe79cfe9 /drivers/gpu/drm/nouveau/core/engine/fifo | |
parent | drm/nouveau/core: move handle-based object apis to handle.c (diff) | |
download | linux-dev-79ca27706a034b683196c85f5c6901b78e5ab8f0.tar.xz linux-dev-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/core/engine/fifo')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/base.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | 39 |
5 files changed, 108 insertions, 38 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c index 56ed3d73bf8e..812d85dc9f52 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c @@ -31,6 +31,23 @@ #include <engine/dmaobj.h> #include <engine/fifo.h> +static int +nouveau_fifo_event_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 +nouveau_fifo_event_func = { + .ctor = nouveau_fifo_event_ctor, +}; + int nouveau_fifo_channel_create_(struct nouveau_object *parent, struct nouveau_object *engine, @@ -91,7 +108,7 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent, if (!chan->user) return -EFAULT; - nouveau_event_trigger(priv->cevent, 1, 0); + nvkm_event_send(&priv->cevent, 1, 0, NULL, 0); chan->size = size; return 0; @@ -168,8 +185,8 @@ void nouveau_fifo_destroy(struct nouveau_fifo *priv) { kfree(priv->channel); - nouveau_event_destroy(&priv->uevent); - nouveau_event_destroy(&priv->cevent); + nvkm_event_fini(&priv->uevent); + nvkm_event_fini(&priv->cevent); nouveau_engine_destroy(&priv->base); } @@ -194,11 +211,7 @@ nouveau_fifo_create_(struct nouveau_object *parent, if (!priv->channel) return -ENOMEM; - ret = nouveau_event_create(1, 1, &priv->cevent); - if (ret) - return ret; - - ret = nouveau_event_create(1, 1, &priv->uevent); + ret = nvkm_event_init(&nouveau_fifo_event_func, 1, 1, &priv->cevent); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c index c61b16a63884..921062c7e5e4 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c @@ -539,7 +539,7 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) } if (status & 0x40000000) { - nouveau_event_trigger(priv->base.uevent, 1, 0); + nvkm_event_send(&priv->base.uevent, 1, 0, NULL, 0); nv_wr32(priv, 0x002100, 0x40000000); status &= ~0x40000000; } diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c index 6e5ac16e5460..0bf844d6db8a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c @@ -389,20 +389,39 @@ nv84_fifo_cclass = { ******************************************************************************/ static void -nv84_fifo_uevent_enable(struct nouveau_event *event, int type, int index) +nv84_fifo_uevent_init(struct nvkm_event *event, int type, int index) { - struct nv84_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x40000000, 0x40000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + nv_mask(fifo, 0x002140, 0x40000000, 0x40000000); } static void -nv84_fifo_uevent_disable(struct nouveau_event *event, int type, int index) +nv84_fifo_uevent_fini(struct nvkm_event *event, int type, int index) { - struct nv84_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x40000000, 0x00000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + 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, + .init = nv84_fifo_uevent_init, + .fini = nv84_fifo_uevent_fini, +}; + +static int nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) @@ -425,9 +444,9 @@ nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - priv->base.uevent->enable = nv84_fifo_uevent_enable; - priv->base.uevent->disable = nv84_fifo_uevent_disable; - priv->base.uevent->priv = priv; + ret = nvkm_event_init(&nv84_fifo_uevent_func, 1, 1, &priv->base.uevent); + if (ret) + return ret; nv_subdev(priv)->unit = 0x00000100; nv_subdev(priv)->intr = nv04_fifo_intr; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index ae4a4dc5642a..bd7bf3c65bc6 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c @@ -730,7 +730,7 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn) for (unkn = 0; unkn < 8; unkn++) { u32 ints = (intr >> (unkn * 0x04)) & inte; if (ints & 0x1) { - nouveau_event_trigger(priv->base.uevent, 1, 0); + nvkm_event_send(&priv->base.uevent, 1, 0, NULL, 0); ints &= ~1; } if (ints) { @@ -827,20 +827,39 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev) } static void -nvc0_fifo_uevent_enable(struct nouveau_event *event, int type, int index) +nvc0_fifo_uevent_init(struct nvkm_event *event, int type, int index) { - struct nvc0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x80000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + nv_mask(fifo, 0x002140, 0x80000000, 0x80000000); } static void -nvc0_fifo_uevent_disable(struct nouveau_event *event, int type, int index) +nvc0_fifo_uevent_fini(struct nvkm_event *event, int type, int index) { - struct nvc0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x00000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + 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, + .init = nvc0_fifo_uevent_init, + .fini = nvc0_fifo_uevent_fini, +}; + +static int nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) @@ -877,9 +896,9 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - priv->base.uevent->enable = nvc0_fifo_uevent_enable; - priv->base.uevent->disable = nvc0_fifo_uevent_disable; - priv->base.uevent->priv = priv; + ret = nvkm_event_init(&nvc0_fifo_uevent_func, 1, 1, &priv->base.uevent); + if (ret) + return ret; nv_subdev(priv)->unit = 0x00000100; nv_subdev(priv)->intr = nvc0_fifo_intr; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 298063edb92d..3e7f03dc822f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -859,7 +859,7 @@ nve0_fifo_intr_runlist(struct nve0_fifo_priv *priv) static void nve0_fifo_intr_engine(struct nve0_fifo_priv *priv) { - nouveau_event_trigger(priv->base.uevent, 1, 0); + nvkm_event_send(&priv->base.uevent, 1, 0, NULL, 0); } static void @@ -952,19 +952,38 @@ nve0_fifo_intr(struct nouveau_subdev *subdev) } static void -nve0_fifo_uevent_enable(struct nouveau_event *event, int type, int index) +nve0_fifo_uevent_init(struct nvkm_event *event, int type, int index) { - struct nve0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x80000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + nv_mask(fifo, 0x002140, 0x80000000, 0x80000000); } static void -nve0_fifo_uevent_disable(struct nouveau_event *event, int type, int index) +nve0_fifo_uevent_fini(struct nvkm_event *event, int type, int index) { - struct nve0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x00000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + 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, + .init = nve0_fifo_uevent_init, + .fini = nve0_fifo_uevent_fini, +}; + int nve0_fifo_fini(struct nouveau_object *object, bool suspend) { @@ -1067,9 +1086,9 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - priv->base.uevent->enable = nve0_fifo_uevent_enable; - priv->base.uevent->disable = nve0_fifo_uevent_disable; - priv->base.uevent->priv = priv; + ret = nvkm_event_init(&nve0_fifo_uevent_func, 1, 1, &priv->base.uevent); + if (ret) + return ret; nv_subdev(priv)->unit = 0x00000100; nv_subdev(priv)->intr = nve0_fifo_intr; |