aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_display.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-08-10 04:10:20 +1000
committerBen Skeggs <bskeggs@redhat.com>2014-08-10 05:13:02 +1000
commit79ca27706a034b683196c85f5c6901b78e5ab8f0 (patch)
treec06ff32b983e4456b3af679288dad97bfe79cfe9 /drivers/gpu/drm/nouveau/nouveau_display.c
parentdrm/nouveau/core: move handle-based object apis to handle.c (diff)
downloadlinux-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/nouveau_display.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index a1247f258240..ff43b41af2e1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -40,13 +40,15 @@
#include <engine/disp.h>
#include <core/class.h>
+#include <nvif/event.h>
static int
-nouveau_display_vblank_handler(void *data, u32 type, int head)
+nouveau_display_vblank_handler(struct nvkm_notify *notify)
{
- struct nouveau_crtc *nv_crtc = data;
+ struct nouveau_crtc *nv_crtc =
+ container_of(notify, typeof(*nv_crtc), vblank);
drm_handle_vblank(nv_crtc->base.dev, nv_crtc->index);
- return NVKM_EVENT_KEEP;
+ return NVKM_NOTIFY_KEEP;
}
int
@@ -56,7 +58,7 @@ nouveau_display_vblank_enable(struct drm_device *dev, int head)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (nv_crtc->index == head) {
- nouveau_event_get(nv_crtc->vblank);
+ nvkm_notify_get(&nv_crtc->vblank);
return 0;
}
}
@@ -70,7 +72,7 @@ nouveau_display_vblank_disable(struct drm_device *dev, int head)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (nv_crtc->index == head) {
- nouveau_event_put(nv_crtc->vblank);
+ nvkm_notify_put(&nv_crtc->vblank);
return;
}
}
@@ -165,7 +167,7 @@ nouveau_display_vblank_fini(struct drm_device *dev)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- nouveau_event_ref(NULL, &nv_crtc->vblank);
+ nvkm_notify_fini(&nv_crtc->vblank);
}
}
@@ -179,9 +181,14 @@ nouveau_display_vblank_init(struct drm_device *dev)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- ret = nouveau_event_new(pdisp->vblank, 1, nv_crtc->index,
- nouveau_display_vblank_handler,
- nv_crtc, &nv_crtc->vblank);
+ ret = nvkm_notify_init(&pdisp->vblank,
+ nouveau_display_vblank_handler, false,
+ &(struct nvif_notify_head_req_v0) {
+ .head = nv_crtc->index,
+ },
+ sizeof(struct nvif_notify_head_req_v0),
+ sizeof(struct nvif_notify_head_rep_v0),
+ &nv_crtc->vblank);
if (ret) {
nouveau_display_vblank_fini(dev);
return ret;
@@ -359,7 +366,7 @@ nouveau_display_init(struct drm_device *dev)
/* enable hotplug interrupts */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct nouveau_connector *conn = nouveau_connector(connector);
- if (conn->hpd) nouveau_event_get(conn->hpd);
+ nvkm_notify_get(&conn->hpd);
}
return ret;
@@ -379,7 +386,7 @@ nouveau_display_fini(struct drm_device *dev)
/* disable hotplug interrupts */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct nouveau_connector *conn = nouveau_connector(connector);
- if (conn->hpd) nouveau_event_put(conn->hpd);
+ nvkm_notify_put(&conn->hpd);
}
drm_kms_helper_poll_disable(dev);